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 "vbaborders.hxx"
20 #include <ooo/vba/word/XBorder.hpp>
21 #include <ooo/vba/word/WdBorderType.hpp>
22 #include <ooo/vba/word/WdLineStyle.hpp>
23 #include <sal/macros.h>
24 #include <cppuhelper/implbase.hxx>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/table/TableBorder.hpp>
28 #include "vbapalette.hxx"
30 using namespace ::com::sun::star
;
31 using namespace ::ooo::vba
;
33 typedef ::cppu::WeakImplHelper
<container::XIndexAccess
> RangeBorders_Base
;
34 typedef InheritedHelperInterfaceWeakImpl
<word::XBorder
> SwVbaBorder_Base
;
36 // #TODO sort these indexes to match the order in which Word iterates over the
37 // borders, the enumeration will match the order in this list
38 const sal_Int16 supportedIndexTable
[] = { word::WdBorderType::wdBorderBottom
, word::WdBorderType::wdBorderDiagonalDown
, word::WdBorderType::wdBorderDiagonalUp
, word::WdBorderType::wdBorderHorizontal
, word::WdBorderType::wdBorderLeft
, word::WdBorderType::wdBorderRight
, word::WdBorderType::wdBorderTop
, word::WdBorderType::wdBorderVertical
};
40 // Equiv widths in 1/100 mm
41 const sal_Int32 OOLineHairline
= 2;
45 class SwVbaBorder
: public SwVbaBorder_Base
48 uno::Reference
< beans::XPropertySet
> m_xProps
;
50 void setBorderLine( table::BorderLine
const & rBorderLine
)
52 table::TableBorder aTableBorder
;
53 m_xProps
->getPropertyValue( "TableBorder" ) >>= aTableBorder
;
57 case word::WdBorderType::wdBorderLeft
:
58 aTableBorder
.IsLeftLineValid
= true;
59 aTableBorder
.LeftLine
= rBorderLine
;
61 case word::WdBorderType::wdBorderTop
:
62 aTableBorder
.IsTopLineValid
= true;
63 aTableBorder
.TopLine
= rBorderLine
;
66 case word::WdBorderType::wdBorderBottom
:
67 aTableBorder
.IsBottomLineValid
= true;
68 aTableBorder
.BottomLine
= rBorderLine
;
70 case word::WdBorderType::wdBorderRight
:
71 aTableBorder
.IsRightLineValid
= true;
72 aTableBorder
.RightLine
= rBorderLine
;
74 case word::WdBorderType::wdBorderVertical
:
75 aTableBorder
.IsVerticalLineValid
= true;
76 aTableBorder
.VerticalLine
= rBorderLine
;
78 case word::WdBorderType::wdBorderHorizontal
:
79 aTableBorder
.IsHorizontalLineValid
= true;
80 aTableBorder
.HorizontalLine
= rBorderLine
;
82 case word::WdBorderType::wdBorderDiagonalDown
:
83 case word::WdBorderType::wdBorderDiagonalUp
:
84 // #TODO have to ignore at the moment, would be
85 // nice to investigate what we can do here
90 m_xProps
->setPropertyValue( "TableBorder", uno::Any(aTableBorder
) );
93 bool getBorderLine( table::BorderLine
& rBorderLine
)
95 table::TableBorder aTableBorder
;
96 m_xProps
->getPropertyValue( "TableBorder" ) >>= aTableBorder
;
99 case word::WdBorderType::wdBorderLeft
:
100 if ( aTableBorder
.IsLeftLineValid
)
101 rBorderLine
= aTableBorder
.LeftLine
;
103 case word::WdBorderType::wdBorderTop
:
104 if ( aTableBorder
.IsTopLineValid
)
105 rBorderLine
= aTableBorder
.TopLine
;
107 case word::WdBorderType::wdBorderBottom
:
108 if ( aTableBorder
.IsBottomLineValid
)
109 rBorderLine
= aTableBorder
.BottomLine
;
111 case word::WdBorderType::wdBorderRight
:
112 if ( aTableBorder
.IsRightLineValid
)
113 rBorderLine
= aTableBorder
.RightLine
;
115 case word::WdBorderType::wdBorderVertical
:
116 if ( aTableBorder
.IsVerticalLineValid
)
117 rBorderLine
= aTableBorder
.VerticalLine
;
119 case word::WdBorderType::wdBorderHorizontal
:
120 if ( aTableBorder
.IsHorizontalLineValid
)
121 rBorderLine
= aTableBorder
.HorizontalLine
;
124 case word::WdBorderType::wdBorderDiagonalDown
:
125 case word::WdBorderType::wdBorderDiagonalUp
:
126 // #TODO have to ignore at the moment, would be
127 // nice to investigate what we can do here
136 virtual OUString
getServiceImplName() override
138 return "SwVbaBorder";
141 virtual css::uno::Sequence
<OUString
> getServiceNames() override
143 static uno::Sequence
< OUString
> const aServiceNames
145 "ooo.vba.word.Border"
147 return aServiceNames
;
150 SwVbaBorder( const uno::Reference
< beans::XPropertySet
> & xProps
, const uno::Reference
< uno::XComponentContext
>& xContext
, sal_Int32 lineType
) : SwVbaBorder_Base( uno::Reference
< XHelperInterface
>( xProps
, uno::UNO_QUERY
), xContext
), m_xProps( xProps
), m_LineType( lineType
) {}
152 uno::Any SAL_CALL
getLineStyle() override
154 sal_Int32 nLineStyle
= word::WdLineStyle::wdLineStyleNone
;
155 table::BorderLine aBorderLine
;
156 if ( getBorderLine( aBorderLine
) )
158 if( aBorderLine
.InnerLineWidth
!=0 && aBorderLine
.OuterLineWidth
!=0 )
160 nLineStyle
= word::WdLineStyle::wdLineStyleDouble
;
162 else if( aBorderLine
.InnerLineWidth
!=0 || aBorderLine
.OuterLineWidth
!=0 )
164 nLineStyle
= word::WdLineStyle::wdLineStyleSingle
;
168 nLineStyle
= word::WdLineStyle::wdLineStyleNone
;
171 return uno::Any( nLineStyle
);
173 void SAL_CALL
setLineStyle( const uno::Any
& _linestyle
) override
175 // Urk no choice but to silently ignore we don't support this attribute
176 // #TODO would be nice to support the word line styles
177 sal_Int32 nLineStyle
= 0;
178 _linestyle
>>= nLineStyle
;
179 table::BorderLine aBorderLine
;
180 if ( !getBorderLine( aBorderLine
) )
181 throw uno::RuntimeException("Method failed" );
183 switch ( nLineStyle
)
185 case word::WdLineStyle::wdLineStyleNone
:
187 aBorderLine
.InnerLineWidth
= 0;
188 aBorderLine
.OuterLineWidth
= 0;
191 case word::WdLineStyle::wdLineStyleDashDot
:
192 case word::WdLineStyle::wdLineStyleDashDotDot
:
193 case word::WdLineStyle::wdLineStyleDashDotStroked
:
194 case word::WdLineStyle::wdLineStyleDashLargeGap
:
195 case word::WdLineStyle::wdLineStyleDashSmallGap
:
196 case word::WdLineStyle::wdLineStyleDot
:
197 case word::WdLineStyle::wdLineStyleDouble
:
198 case word::WdLineStyle::wdLineStyleDoubleWavy
:
199 case word::WdLineStyle::wdLineStyleEmboss3D
:
200 case word::WdLineStyle::wdLineStyleEngrave3D
:
201 case word::WdLineStyle::wdLineStyleInset
:
202 case word::WdLineStyle::wdLineStyleOutset
:
203 case word::WdLineStyle::wdLineStyleSingle
:
204 case word::WdLineStyle::wdLineStyleSingleWavy
:
205 case word::WdLineStyle::wdLineStyleThickThinLargeGap
:
206 case word::WdLineStyle::wdLineStyleThickThinMedGap
:
207 case word::WdLineStyle::wdLineStyleThickThinSmallGap
:
208 case word::WdLineStyle::wdLineStyleThinThickLargeGap
:
209 case word::WdLineStyle::wdLineStyleThinThickMedGap
:
210 case word::WdLineStyle::wdLineStyleThinThickSmallGap
:
211 case word::WdLineStyle::wdLineStyleThinThickThinLargeGap
:
212 case word::WdLineStyle::wdLineStyleThinThickThinMedGap
:
213 case word::WdLineStyle::wdLineStyleThinThickThinSmallGap
:
214 case word::WdLineStyle::wdLineStyleTriple
:
216 aBorderLine
.InnerLineWidth
= 0;
217 aBorderLine
.OuterLineWidth
= OOLineHairline
;
221 throw uno::RuntimeException("Bad param" );
223 setBorderLine( aBorderLine
);
228 class RangeBorders
: public RangeBorders_Base
231 uno::Reference
< table::XCellRange
> m_xRange
;
232 uno::Reference
< uno::XComponentContext
> m_xContext
;
233 VbaPalette m_Palette
;
234 sal_Int32
getTableIndex( sal_Int32 nConst
)
236 // okay return position of the index in the table
237 sal_Int32 nIndexes
= getCount();
238 sal_Int32 realIndex
= 0;
239 const sal_Int16
* pTableEntry
= supportedIndexTable
;
240 for ( ; realIndex
< nIndexes
; ++realIndex
, ++pTableEntry
)
242 if ( *pTableEntry
== nConst
)
245 return getCount(); // error condition
248 RangeBorders( uno::Reference
< table::XCellRange
> xRange
, uno::Reference
< uno::XComponentContext
> xContext
, VbaPalette aPalette
) : m_xRange(std::move( xRange
)), m_xContext(std::move( xContext
)), m_Palette(std::move( aPalette
))
252 virtual ::sal_Int32 SAL_CALL
getCount( ) override
254 return SAL_N_ELEMENTS( supportedIndexTable
);
256 virtual uno::Any SAL_CALL
getByIndex( ::sal_Int32 Index
) override
259 sal_Int32 nIndex
= getTableIndex( Index
);
260 if ( nIndex
>= 0 && nIndex
< getCount() )
262 uno::Reference
< beans::XPropertySet
> xProps( m_xRange
, uno::UNO_QUERY_THROW
);
263 return uno::Any( uno::Reference
< word::XBorder
>( new SwVbaBorder( xProps
, m_xContext
, supportedIndexTable
[ nIndex
] )) );
265 throw lang::IndexOutOfBoundsException();
267 virtual uno::Type SAL_CALL
getElementType( ) override
269 return cppu::UnoType
<word::XBorder
>::get();
271 virtual sal_Bool SAL_CALL
hasElements( ) override
279 static uno::Reference
< container::XIndexAccess
>
280 rangeToBorderIndexAccess( const uno::Reference
< table::XCellRange
>& xRange
, const uno::Reference
< uno::XComponentContext
> & xContext
, VbaPalette
const & rPalette
)
282 return new RangeBorders( xRange
, xContext
, rPalette
);
287 class RangeBorderEnumWrapper
: public EnumerationHelper_BASE
289 uno::Reference
<container::XIndexAccess
> m_xIndexAccess
;
292 explicit RangeBorderEnumWrapper( uno::Reference
< container::XIndexAccess
> xIndexAccess
) : m_xIndexAccess(std::move( xIndexAccess
)), m_nIndex( 0 ) {}
293 virtual sal_Bool SAL_CALL
hasMoreElements( ) override
295 return ( m_nIndex
< m_xIndexAccess
->getCount() );
298 virtual uno::Any SAL_CALL
nextElement( ) override
300 if ( m_nIndex
< m_xIndexAccess
->getCount() )
301 return m_xIndexAccess
->getByIndex( m_nIndex
++ );
302 throw container::NoSuchElementException();
309 SwVbaBorders::SwVbaBorders( const uno::Reference
< XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
> & xContext
, const uno::Reference
< table::XCellRange
>& xRange
, VbaPalette
const & rPalette
): SwVbaBorders_BASE( xParent
, xContext
, rangeToBorderIndexAccess( xRange
,xContext
, rPalette
) )
311 m_xProps
.set( xRange
, uno::UNO_QUERY_THROW
);
314 uno::Reference
< container::XEnumeration
>
315 SwVbaBorders::createEnumeration()
317 return new RangeBorderEnumWrapper( m_xIndexAccess
);
321 SwVbaBorders::createCollectionObject( const css::uno::Any
& aSource
)
323 return aSource
; // it's already a Border object
327 SwVbaBorders::getElementType()
329 return cppu::UnoType
<word::XBorders
>::get();
333 SwVbaBorders::getItemByIntIndex( const sal_Int32 nIndex
)
335 return createCollectionObject( m_xIndexAccess
->getByIndex( nIndex
) );
338 sal_Bool SAL_CALL
SwVbaBorders::getShadow()
340 // always return False for table border in MS Word
344 void SAL_CALL
SwVbaBorders::setShadow( sal_Bool
/*_shadow*/ )
346 // not support in Table border in Word
351 SwVbaBorders::getServiceImplName()
353 return "SwVbaBorders";
356 uno::Sequence
< OUString
>
357 SwVbaBorders::getServiceNames()
359 static uno::Sequence
< OUString
> const aServiceNames
361 "ooo.vba.word.Borders"
363 return aServiceNames
;
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */