1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vbaborders.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include "vbaborders.hxx"
31 #include <ooo/vba/word/XBorder.hpp>
32 #include <ooo/vba/word/WdBorderType.hpp>
33 #include <ooo/vba/word/WdLineStyle.hpp>
34 #include <cppuhelper/implbase3.hxx>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/table/TableBorder.hpp>
37 #include <com/sun/star/table/ShadowFormat.hpp>
38 #include <com/sun/star/table/ShadowLocation.hpp>
39 #include "vbapalette.hxx"
41 using namespace ::com::sun::star
;
42 using namespace ::ooo::vba
;
45 typedef ::cppu::WeakImplHelper1
<container::XIndexAccess
> RangeBorders_Base
;
46 typedef InheritedHelperInterfaceImpl1
<word::XBorder
> SwVbaBorder_Base
;
48 // #TODO sort these indexes to match the order in which Word iterates over the
49 // borders, the enumeration will match the order in this list
50 static 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
};
52 const static rtl::OUString
sTableBorder( RTL_CONSTASCII_USTRINGPARAM("TableBorder") );
54 // Equiv widths in in 1/100 mm
55 const static sal_Int32 OOLineThin
= 35;
56 const static sal_Int32 OOLineMedium
= 88;
57 const static sal_Int32 OOLineThick
= 141;
58 const static sal_Int32 OOLineHairline
= 2;
60 class SwVbaBorder
: public SwVbaBorder_Base
63 uno::Reference
< beans::XPropertySet
> m_xProps
;
66 bool setBorderLine( table::BorderLine
& rBorderLine
)
68 table::TableBorder aTableBorder
;
69 m_xProps
->getPropertyValue( sTableBorder
) >>= aTableBorder
;
73 case word::WdBorderType::wdBorderLeft
:
74 aTableBorder
.IsLeftLineValid
= sal_True
;
75 aTableBorder
.LeftLine
= rBorderLine
;
77 case word::WdBorderType::wdBorderTop
:
78 aTableBorder
.IsTopLineValid
= sal_True
;
79 aTableBorder
.TopLine
= rBorderLine
;
82 case word::WdBorderType::wdBorderBottom
:
83 aTableBorder
.IsBottomLineValid
= sal_True
;
84 aTableBorder
.BottomLine
= rBorderLine
;
86 case word::WdBorderType::wdBorderRight
:
87 aTableBorder
.IsRightLineValid
= sal_True
;
88 aTableBorder
.RightLine
= rBorderLine
;
90 case word::WdBorderType::wdBorderVertical
:
91 aTableBorder
.IsVerticalLineValid
= sal_True
;
92 aTableBorder
.VerticalLine
= rBorderLine
;
94 case word::WdBorderType::wdBorderHorizontal
:
95 aTableBorder
.IsHorizontalLineValid
= sal_True
;
96 aTableBorder
.HorizontalLine
= rBorderLine
;
98 case word::WdBorderType::wdBorderDiagonalDown
:
99 case word::WdBorderType::wdBorderDiagonalUp
:
100 // #TODO have to ignore at the momement, would be
101 // nice to investigate what we can do here
106 m_xProps
->setPropertyValue( sTableBorder
, uno::makeAny(aTableBorder
) );
110 bool getBorderLine( table::BorderLine
& rBorderLine
)
112 table::TableBorder aTableBorder
;
113 m_xProps
->getPropertyValue( sTableBorder
) >>= aTableBorder
;
114 switch ( m_LineType
)
116 case word::WdBorderType::wdBorderLeft
:
117 if ( aTableBorder
.IsLeftLineValid
)
118 rBorderLine
= aTableBorder
.LeftLine
;
120 case word::WdBorderType::wdBorderTop
:
121 if ( aTableBorder
.IsTopLineValid
)
122 rBorderLine
= aTableBorder
.TopLine
;
124 case word::WdBorderType::wdBorderBottom
:
125 if ( aTableBorder
.IsBottomLineValid
)
126 rBorderLine
= aTableBorder
.BottomLine
;
128 case word::WdBorderType::wdBorderRight
:
129 if ( aTableBorder
.IsRightLineValid
)
130 rBorderLine
= aTableBorder
.RightLine
;
132 case word::WdBorderType::wdBorderVertical
:
133 if ( aTableBorder
.IsVerticalLineValid
)
134 rBorderLine
= aTableBorder
.VerticalLine
;
136 case word::WdBorderType::wdBorderHorizontal
:
137 if ( aTableBorder
.IsHorizontalLineValid
)
138 rBorderLine
= aTableBorder
.HorizontalLine
;
141 case word::WdBorderType::wdBorderDiagonalDown
:
142 case word::WdBorderType::wdBorderDiagonalUp
:
143 // #TODO have to ignore at the momement, would be
144 // nice to investigate what we can do here
151 SwVbaBorder(); // no impl
153 virtual rtl::OUString
& getServiceImplName()
155 static rtl::OUString
sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaBorder") );
158 virtual css::uno::Sequence
<rtl::OUString
> getServiceNames()
160 static uno::Sequence
< rtl::OUString
> aServiceNames
;
161 if ( aServiceNames
.getLength() == 0 )
163 aServiceNames
.realloc( 1 );
164 aServiceNames
[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.Border" ) );
166 return aServiceNames
;
169 SwVbaBorder( const uno::Reference
< beans::XPropertySet
> & xProps
, const uno::Reference
< uno::XComponentContext
>& xContext
, sal_Int32 lineType
, VbaPalette
& rPalette
) : SwVbaBorder_Base( uno::Reference
< XHelperInterface
>( xProps
, uno::UNO_QUERY
), xContext
), m_xProps( xProps
), m_LineType( lineType
), m_Palette( rPalette
) {}
171 uno::Any SAL_CALL
getLineStyle() throw (uno::RuntimeException
)
173 sal_Int32 nLineStyle
= word::WdLineStyle::wdLineStyleNone
;
174 table::BorderLine aBorderLine
;
175 if ( getBorderLine( aBorderLine
) )
177 if( aBorderLine
.InnerLineWidth
!=0 && aBorderLine
.OuterLineWidth
!=0 )
179 nLineStyle
= word::WdLineStyle::wdLineStyleDouble
;
181 else if( aBorderLine
.InnerLineWidth
!=0 || aBorderLine
.OuterLineWidth
!=0 )
183 nLineStyle
= word::WdLineStyle::wdLineStyleSingle
;
187 nLineStyle
= word::WdLineStyle::wdLineStyleNone
;
190 return uno::makeAny( nLineStyle
);
192 void SAL_CALL
setLineStyle( const uno::Any
& _linestyle
) throw (uno::RuntimeException
)
194 // Urk no choice but to silently ignore we don't support this attribute
195 // #TODO would be nice to support the word line styles
196 sal_Int32 nLineStyle
= 0;
197 _linestyle
>>= nLineStyle
;
198 table::BorderLine aBorderLine
;
199 if ( getBorderLine( aBorderLine
) )
201 switch ( nLineStyle
)
203 case word::WdLineStyle::wdLineStyleNone
:
205 aBorderLine
.InnerLineWidth
= 0;
206 aBorderLine
.OuterLineWidth
= 0;
209 case word::WdLineStyle::wdLineStyleDashDot
:
210 case word::WdLineStyle::wdLineStyleDashDotDot
:
211 case word::WdLineStyle::wdLineStyleDashDotStroked
:
212 case word::WdLineStyle::wdLineStyleDashLargeGap
:
213 case word::WdLineStyle::wdLineStyleDashSmallGap
:
214 case word::WdLineStyle::wdLineStyleDot
:
215 case word::WdLineStyle::wdLineStyleDouble
:
216 case word::WdLineStyle::wdLineStyleDoubleWavy
:
217 case word::WdLineStyle::wdLineStyleEmboss3D
:
218 case word::WdLineStyle::wdLineStyleEngrave3D
:
219 case word::WdLineStyle::wdLineStyleInset
:
220 case word::WdLineStyle::wdLineStyleOutset
:
221 case word::WdLineStyle::wdLineStyleSingle
:
222 case word::WdLineStyle::wdLineStyleSingleWavy
:
223 case word::WdLineStyle::wdLineStyleThickThinLargeGap
:
224 case word::WdLineStyle::wdLineStyleThickThinMedGap
:
225 case word::WdLineStyle::wdLineStyleThickThinSmallGap
:
226 case word::WdLineStyle::wdLineStyleThinThickLargeGap
:
227 case word::WdLineStyle::wdLineStyleThinThickMedGap
:
228 case word::WdLineStyle::wdLineStyleThinThickSmallGap
:
229 case word::WdLineStyle::wdLineStyleThinThickThinLargeGap
:
230 case word::WdLineStyle::wdLineStyleThinThickThinMedGap
:
231 case word::WdLineStyle::wdLineStyleThinThickThinSmallGap
:
232 case word::WdLineStyle::wdLineStyleTriple
:
234 aBorderLine
.InnerLineWidth
= 0;
235 aBorderLine
.OuterLineWidth
= OOLineHairline
;
239 throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Bad param" ) ), uno::Reference
< uno::XInterface
>() );
241 setBorderLine( aBorderLine
);
244 throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Method failed" ) ), uno::Reference
< uno::XInterface
>() );
248 class RangeBorders
: public RangeBorders_Base
251 uno::Reference
< table::XCellRange
> m_xRange
;
252 uno::Reference
< uno::XComponentContext
> m_xContext
;
253 VbaPalette m_Palette
;
254 sal_Int32
getTableIndex( sal_Int32 nConst
)
256 // hokay return position of the index in the table
257 sal_Int32 nIndexes
= getCount();
258 sal_Int32 realIndex
= 0;
259 const sal_Int16
* pTableEntry
= supportedIndexTable
;
260 for ( ; realIndex
< nIndexes
; ++realIndex
, ++pTableEntry
)
262 if ( *pTableEntry
== nConst
)
265 return getCount(); // error condition
268 RangeBorders( const uno::Reference
< table::XCellRange
>& xRange
, const uno::Reference
< uno::XComponentContext
> & xContext
, VbaPalette
& rPalette
) : m_xRange( xRange
), m_xContext( xContext
), m_Palette( rPalette
)
272 virtual ::sal_Int32 SAL_CALL
getCount( ) throw (uno::RuntimeException
)
274 return sizeof( supportedIndexTable
) / sizeof( supportedIndexTable
[0] );
276 virtual uno::Any SAL_CALL
getByIndex( ::sal_Int32 Index
) throw (lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
)
279 sal_Int32 nIndex
= getTableIndex( Index
);
280 if ( nIndex
>= 0 && nIndex
< getCount() )
282 uno::Reference
< beans::XPropertySet
> xProps( m_xRange
, uno::UNO_QUERY_THROW
);
283 return uno::makeAny( uno::Reference
< word::XBorder
>( new SwVbaBorder( xProps
, m_xContext
, supportedIndexTable
[ nIndex
], m_Palette
)) );
285 throw lang::IndexOutOfBoundsException();
287 virtual uno::Type SAL_CALL
getElementType( ) throw (uno::RuntimeException
)
289 return word::XBorder::static_type(0);
291 virtual ::sal_Bool SAL_CALL
hasElements( ) throw (uno::RuntimeException
)
297 uno::Reference
< container::XIndexAccess
>
298 rangeToBorderIndexAccess( const uno::Reference
< table::XCellRange
>& xRange
, const uno::Reference
< uno::XComponentContext
> & xContext
, VbaPalette
& rPalette
)
300 return new RangeBorders( xRange
, xContext
, rPalette
);
303 class RangeBorderEnumWrapper
: public EnumerationHelper_BASE
305 uno::Reference
<container::XIndexAccess
> m_xIndexAccess
;
308 RangeBorderEnumWrapper( const uno::Reference
< container::XIndexAccess
>& xIndexAccess
) : m_xIndexAccess( xIndexAccess
), nIndex( 0 ) {}
309 virtual ::sal_Bool SAL_CALL
hasMoreElements( ) throw (uno::RuntimeException
)
311 return ( nIndex
< m_xIndexAccess
->getCount() );
314 virtual uno::Any SAL_CALL
nextElement( ) throw (container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
)
316 if ( nIndex
< m_xIndexAccess
->getCount() )
317 return m_xIndexAccess
->getByIndex( nIndex
++ );
318 throw container::NoSuchElementException();
323 SwVbaBorders::SwVbaBorders( const uno::Reference
< XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
> & xContext
, const uno::Reference
< table::XCellRange
>& xRange
, VbaPalette
& rPalette
): SwVbaBorders_BASE( xParent
, xContext
, rangeToBorderIndexAccess( xRange
,xContext
, rPalette
) )
325 m_xProps
.set( xRange
, uno::UNO_QUERY_THROW
);
328 uno::Reference
< container::XEnumeration
>
329 SwVbaBorders::createEnumeration() throw (uno::RuntimeException
)
331 return new RangeBorderEnumWrapper( m_xIndexAccess
);
335 SwVbaBorders::createCollectionObject( const css::uno::Any
& aSource
)
337 return aSource
; // its already a Border object
341 SwVbaBorders::getElementType() throw (uno::RuntimeException
)
343 return word::XBorders::static_type(0);
347 SwVbaBorders::getItemByIntIndex( const sal_Int32 nIndex
) throw (uno::RuntimeException
)
349 return createCollectionObject( m_xIndexAccess
->getByIndex( nIndex
) );
352 sal_Bool SAL_CALL
SwVbaBorders::getShadow() throw (uno::RuntimeException
)
354 table::ShadowFormat aShadowFormat
;
355 m_xProps
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ShadowFormat") ) ) >>= aShadowFormat
;
356 return ( aShadowFormat
.Location
!= table::ShadowLocation_NONE
);
359 void SAL_CALL
SwVbaBorders::setShadow( sal_Bool
/*_shadow*/ ) throw (uno::RuntimeException
)
361 throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference
< uno::XInterface
>() );
365 SwVbaBorders::getServiceImplName()
367 static rtl::OUString
sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaBorders") );
371 uno::Sequence
< rtl::OUString
>
372 SwVbaBorders::getServiceNames()
374 static uno::Sequence
< rtl::OUString
> aServiceNames
;
375 if ( aServiceNames
.getLength() == 0 )
377 aServiceNames
.realloc( 1 );
378 aServiceNames
[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.Borders" ) );
380 return aServiceNames
;