fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / vba / vbaborders.cxx
blob1056713f03ef212156129941d2f8d091dbf9a99a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
21 #include <sal/macros.h>
22 #include <cppuhelper/implbase3.hxx>
23 #include <ooo/vba/excel/XlBordersIndex.hpp>
24 #include <ooo/vba/excel/XlBorderWeight.hpp>
25 #include <ooo/vba/excel/XlLineStyle.hpp>
26 #include <ooo/vba/excel/XlColorIndex.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/table/TableBorder.hpp>
29 #include <com/sun/star/table/XColumnRowRange.hpp>
31 #include "vbapalette.hxx"
33 using namespace ::com::sun::star;
34 using namespace ::ooo::vba;
35 using namespace ::ooo::vba::excel;
37 typedef ::cppu::WeakImplHelper1<container::XIndexAccess > RangeBorders_Base;
38 typedef InheritedHelperInterfaceImpl1<excel::XBorder > ScVbaBorder_Base;
40 // #TODO sort these indexes to match the order in which Excel iterates over the
41 // borders, the enumeration will match the order in this list
42 static const sal_Int16 supportedIndexTable[] = { XlBordersIndex::xlEdgeLeft, XlBordersIndex::xlEdgeTop, XlBordersIndex::xlEdgeBottom, XlBordersIndex::xlEdgeRight, XlBordersIndex::xlDiagonalDown, XlBordersIndex::xlDiagonalUp, XlBordersIndex::xlInsideVertical, XlBordersIndex::xlInsideHorizontal };
44 static const char sTableBorder[] = "TableBorder";
46 // Equiv widths in 1/100 mm
47 const static sal_Int32 OOLineThin = 35;
48 const static sal_Int32 OOLineMedium = 88;
49 const static sal_Int32 OOLineThick = 141;
50 const static sal_Int32 OOLineHairline = 2;
52 class ScVbaBorder : public ScVbaBorder_Base
54 private:
55 uno::Reference< beans::XPropertySet > m_xProps;
56 sal_Int32 m_LineType;
57 ScVbaPalette m_Palette;
58 bool setBorderLine( table::BorderLine& rBorderLine )
60 table::TableBorder aTableBorder;
61 m_xProps->getPropertyValue( sTableBorder ) >>= aTableBorder;
63 switch ( m_LineType )
65 case XlBordersIndex::xlEdgeLeft:
66 aTableBorder.IsLeftLineValid = sal_True;
67 aTableBorder.LeftLine= rBorderLine;
68 break;
69 case XlBordersIndex::xlEdgeTop:
70 aTableBorder.IsTopLineValid = sal_True;
71 aTableBorder.TopLine = rBorderLine;
72 break;
74 case XlBordersIndex::xlEdgeBottom:
75 aTableBorder.IsBottomLineValid = sal_True;
76 aTableBorder.BottomLine = rBorderLine;
77 break;
78 case XlBordersIndex::xlEdgeRight:
79 aTableBorder.IsRightLineValid = sal_True;
80 aTableBorder.RightLine = rBorderLine;
81 break;
82 case XlBordersIndex::xlInsideVertical:
83 aTableBorder.IsVerticalLineValid = sal_True;
84 aTableBorder.VerticalLine = rBorderLine;
85 break;
86 case XlBordersIndex::xlInsideHorizontal:
87 aTableBorder.IsHorizontalLineValid = sal_True;
88 aTableBorder.HorizontalLine = rBorderLine;
89 break;
90 case XlBordersIndex::xlDiagonalDown:
91 case XlBordersIndex::xlDiagonalUp:
92 // #TODO have to ignore at the momement, would be
93 // nice to investigate what we can do here
94 break;
95 default:
96 return false;
98 m_xProps->setPropertyValue( sTableBorder, uno::makeAny(aTableBorder) );
99 return true;
102 bool getBorderLine( table::BorderLine& rBorderLine )
104 table::TableBorder aTableBorder;
105 m_xProps->getPropertyValue( sTableBorder ) >>= aTableBorder;
106 switch ( m_LineType )
108 case XlBordersIndex::xlEdgeLeft:
109 if ( aTableBorder.IsLeftLineValid )
110 rBorderLine = aTableBorder.LeftLine;
111 break;
112 case XlBordersIndex::xlEdgeTop:
113 if ( aTableBorder.IsTopLineValid )
114 rBorderLine = aTableBorder.TopLine;
115 break;
117 case XlBordersIndex::xlEdgeBottom:
118 if ( aTableBorder.IsBottomLineValid )
119 rBorderLine = aTableBorder.BottomLine;
120 break;
121 case XlBordersIndex::xlEdgeRight:
122 if ( aTableBorder.IsRightLineValid )
123 rBorderLine = aTableBorder.RightLine;
124 break;
125 case XlBordersIndex::xlInsideVertical:
126 if ( aTableBorder.IsVerticalLineValid )
127 rBorderLine = aTableBorder.VerticalLine;
128 break;
129 case XlBordersIndex::xlInsideHorizontal:
130 if ( aTableBorder.IsHorizontalLineValid )
131 rBorderLine = aTableBorder.HorizontalLine;
132 break;
134 case XlBordersIndex::xlDiagonalDown:
135 case XlBordersIndex::xlDiagonalUp:
136 // #TODO have to ignore at the momement, would be
137 // nice to investigate what we can do here
138 break;
139 default:
140 return false;
142 return true;
145 protected:
146 virtual OUString getServiceImplName() SAL_OVERRIDE
148 return OUString("ScVbaBorder");
150 virtual css::uno::Sequence<OUString> getServiceNames() SAL_OVERRIDE
152 static uno::Sequence< OUString > aServiceNames;
153 if ( aServiceNames.getLength() == 0 )
155 aServiceNames.realloc( 1 );
156 aServiceNames[ 0 ] = "ooo.vba.excel.Border";
158 return aServiceNames;
160 public:
161 ScVbaBorder( const uno::Reference< beans::XPropertySet > & xProps, const uno::Reference< uno::XComponentContext >& xContext, sal_Int32 lineType, ScVbaPalette& rPalette) : ScVbaBorder_Base( uno::Reference< XHelperInterface >( xProps, uno::UNO_QUERY ), xContext ), m_xProps( xProps ), m_LineType( lineType ), m_Palette( rPalette ) {}
163 // XBorder
164 uno::Any SAL_CALL getColor() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
166 table::BorderLine aBorderLine;
167 if ( getBorderLine( aBorderLine ) )
168 return uno::makeAny( OORGBToXLRGB( aBorderLine.Color ) );
169 throw uno::RuntimeException("No Implementation available" );
171 void SAL_CALL setColor( const uno::Any& _color ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
173 sal_Int32 nColor = 0;
174 _color >>= nColor;
175 table::BorderLine aBorderLine;
176 if ( getBorderLine( aBorderLine ) )
178 aBorderLine.Color = XLRGBToOORGB( nColor );
179 setBorderLine( aBorderLine );
181 else
182 throw uno::RuntimeException("No Implementation available" );
185 uno::Any SAL_CALL getColorIndex() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
187 sal_Int32 nColor = 0;
188 XLRGBToOORGB( getColor() ) >>= nColor;
189 uno::Reference< container::XIndexAccess > xIndex = m_Palette.getPalette();
190 sal_Int32 nElems = xIndex->getCount();
191 sal_Int32 nIndex = -1;
192 for ( sal_Int32 count=0; count<nElems; ++count )
194 sal_Int32 nPaletteColor = 0;
195 xIndex->getByIndex( count ) >>= nPaletteColor;
196 if ( nPaletteColor == nColor )
198 nIndex = count + 1;
199 break;
202 return uno::makeAny(nIndex);
205 void SAL_CALL setColorIndex( const uno::Any& _colorindex ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
207 sal_Int32 nColor = 0;
208 _colorindex >>= nColor;
209 if ( !nColor || nColor == XlColorIndex::xlColorIndexAutomatic )
210 nColor = 1;
211 setColor( OORGBToXLRGB( m_Palette.getPalette()->getByIndex( --nColor ) ) );
213 uno::Any SAL_CALL getWeight() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
215 table::BorderLine aBorderLine;
216 if ( getBorderLine( aBorderLine ) )
218 switch ( aBorderLine.OuterLineWidth )
220 case 0: // Thin = default OO thickness
221 case OOLineThin:
222 return uno::makeAny( XlBorderWeight::xlThin );
223 case OOLineMedium:
224 return uno::makeAny( XlBorderWeight::xlMedium );
225 case OOLineThick:
226 return uno::makeAny( XlBorderWeight::xlThick );
227 case OOLineHairline:
228 return uno::makeAny( XlBorderWeight::xlHairline );
229 default:
230 break;
233 throw uno::RuntimeException("Method failed" );
235 void SAL_CALL setWeight( const uno::Any& _weight ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
237 sal_Int32 nWeight = 0;
238 _weight >>= nWeight;
239 table::BorderLine aBorderLine;
240 if ( getBorderLine( aBorderLine ) )
242 switch ( nWeight )
244 case XlBorderWeight::xlThin:
245 aBorderLine.OuterLineWidth = OOLineThin;
246 break;
247 case XlBorderWeight::xlMedium:
248 aBorderLine.OuterLineWidth = OOLineMedium;
249 break;
250 case XlBorderWeight::xlThick:
251 aBorderLine.OuterLineWidth = OOLineThick;
252 break;
253 case XlBorderWeight::xlHairline:
254 aBorderLine.OuterLineWidth = OOLineHairline;
255 break;
256 default:
257 throw uno::RuntimeException("Bad param" );
259 setBorderLine( aBorderLine );
261 else
262 throw uno::RuntimeException("Method failed" );
265 uno::Any SAL_CALL getLineStyle() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
267 // always return xlContinuous;
268 return uno::makeAny( XlLineStyle::xlContinuous );
270 void SAL_CALL setLineStyle( const uno::Any& _linestyle ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
272 // Urk no choice but to silently ignore we don't support this attribute
273 // #TODO would be nice to support the excel line styles
274 sal_Int32 nLineStyle = 0;
275 _linestyle >>= nLineStyle;
276 table::BorderLine aBorderLine;
277 if ( getBorderLine( aBorderLine ) )
279 switch ( nLineStyle )
281 case XlLineStyle::xlContinuous:
282 case XlLineStyle::xlDash:
283 case XlLineStyle::xlDashDot:
284 case XlLineStyle::xlDashDotDot:
285 case XlLineStyle::xlDot:
286 case XlLineStyle::xlDouble:
287 case XlLineStyle::xlLineStyleNone:
288 case XlLineStyle::xlSlantDashDot:
289 break;
290 default:
291 throw uno::RuntimeException("Bad param" );
293 setBorderLine( aBorderLine );
295 else
296 throw uno::RuntimeException("Method failed" );
300 class RangeBorders : public RangeBorders_Base
302 private:
303 uno::Reference< table::XCellRange > m_xRange;
304 uno::Reference< uno::XComponentContext > m_xContext;
305 ScVbaPalette m_Palette;
306 sal_Int32 getTableIndex( sal_Int32 nConst )
308 // hokay return position of the index in the table
309 sal_Int32 nIndexes = getCount();
310 sal_Int32 realIndex = 0;
311 const sal_Int16* pTableEntry = supportedIndexTable;
312 for ( ; realIndex < nIndexes; ++realIndex, ++pTableEntry )
314 if ( *pTableEntry == nConst )
315 return realIndex;
317 return getCount(); // error condition
319 public:
320 RangeBorders( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, ScVbaPalette& rPalette ) : m_xRange( xRange ), m_xContext( xContext ), m_Palette( rPalette )
323 // XIndexAccess
324 virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
326 return sizeof( supportedIndexTable ) / sizeof( supportedIndexTable[0] );
328 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE
331 sal_Int32 nIndex = getTableIndex( Index );
332 if ( nIndex >= 0 && nIndex < getCount() )
334 uno::Reference< beans::XPropertySet > xProps( m_xRange, uno::UNO_QUERY_THROW );
335 return uno::makeAny( uno::Reference< excel::XBorder >( new ScVbaBorder( xProps, m_xContext, supportedIndexTable[ nIndex ], m_Palette )) );
337 throw lang::IndexOutOfBoundsException();
339 virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
341 return cppu::UnoType<excel::XBorder>::get();
343 virtual sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
345 return sal_True;
349 uno::Reference< container::XIndexAccess >
350 rangeToBorderIndexAccess( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, ScVbaPalette& rPalette )
352 return new RangeBorders( xRange, xContext, rPalette );
355 class RangeBorderEnumWrapper : public EnumerationHelper_BASE
357 uno::Reference<container::XIndexAccess > m_xIndexAccess;
358 sal_Int32 nIndex;
359 public:
360 RangeBorderEnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
361 virtual sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
363 return ( nIndex < m_xIndexAccess->getCount() );
366 virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE
368 if ( nIndex < m_xIndexAccess->getCount() )
369 return m_xIndexAccess->getByIndex( nIndex++ );
370 throw container::NoSuchElementException();
374 ScVbaBorders::ScVbaBorders( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< table::XCellRange >& xRange, ScVbaPalette& rPalette ): ScVbaBorders_BASE( xParent, xContext, rangeToBorderIndexAccess( xRange ,xContext, rPalette ) ), bRangeIsSingleCell( false )
376 uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, uno::UNO_QUERY_THROW );
377 if ( xColumnRowRange->getRows()->getCount() == 1 && xColumnRowRange->getColumns()->getCount() == 1 )
378 bRangeIsSingleCell = true;
379 m_xProps.set( xRange, uno::UNO_QUERY_THROW );
382 uno::Reference< container::XEnumeration >
383 ScVbaBorders::createEnumeration() throw (uno::RuntimeException)
385 return new RangeBorderEnumWrapper( m_xIndexAccess );
388 uno::Any
389 ScVbaBorders::createCollectionObject( const css::uno::Any& aSource )
391 return aSource; // its already a Border object
394 uno::Type
395 ScVbaBorders::getElementType() throw (uno::RuntimeException)
397 return cppu::UnoType<excel::XBorders>::get();
400 uno::Any
401 ScVbaBorders::getItemByIntIndex( const sal_Int32 nIndex ) throw (uno::RuntimeException)
403 return createCollectionObject( m_xIndexAccess->getByIndex( nIndex ) );
406 uno::Any SAL_CALL ScVbaBorders::getColor() throw (uno::RuntimeException, std::exception)
408 sal_Int32 count = getCount();
409 uno::Any color;
410 for( sal_Int32 i = 0; i < count ; i++ )
412 if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
414 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
415 if( color.hasValue() )
417 if( color != xBorder->getColor() )
418 return uno::makeAny( uno::Reference< uno::XInterface >() );
420 else
421 color = xBorder->getColor();
424 return color;
426 void SAL_CALL ScVbaBorders::setColor( const uno::Any& _color ) throw (uno::RuntimeException, std::exception)
428 sal_Int32 count = getCount();
429 for( sal_Int32 i = 0; i < count ; i++ )
431 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
432 xBorder->setColor( _color );
435 uno::Any SAL_CALL ScVbaBorders::getColorIndex() throw (uno::RuntimeException, std::exception)
437 sal_Int32 count = getCount();
438 uno::Any nColorIndex;
439 for( sal_Int32 i = 0; i < count ; i++ )
441 if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
443 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
444 if( nColorIndex.hasValue() )
446 if( nColorIndex != xBorder->getColorIndex() )
447 return uno::makeAny( uno::Reference< uno::XInterface >() );
449 else
450 nColorIndex = xBorder->getColorIndex();
453 return nColorIndex;
455 void SAL_CALL ScVbaBorders::setColorIndex( const uno::Any& _colorindex ) throw (uno::RuntimeException, std::exception)
457 sal_Int32 count = getCount();
458 for( sal_Int32 i = 0; i < count ; i++ )
460 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
461 xBorder->setColorIndex( _colorindex );
465 static bool
466 lcl_areAllLineWidthsSame( const table::TableBorder& maTableBorder, bool bIsCell )
469 bool bRes = false;
470 if (bIsCell)
472 bRes = ((maTableBorder.TopLine.OuterLineWidth == maTableBorder.BottomLine.OuterLineWidth) &&
473 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.LeftLine.OuterLineWidth) &&
474 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.RightLine.OuterLineWidth));
476 else
478 bRes = ((maTableBorder.TopLine.OuterLineWidth == maTableBorder.BottomLine.OuterLineWidth) &&
479 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.LeftLine.OuterLineWidth) &&
480 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.HorizontalLine.OuterLineWidth) &&
481 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.VerticalLine.OuterLineWidth) &&
482 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.RightLine.OuterLineWidth));
484 return bRes;
487 uno::Any SAL_CALL ScVbaBorders::getLineStyle() throw (uno::RuntimeException, std::exception)
489 table::TableBorder maTableBorder;
490 m_xProps->getPropertyValue( sTableBorder ) >>= maTableBorder;
492 sal_Int32 aLinestyle = XlLineStyle::xlLineStyleNone;
494 if ( lcl_areAllLineWidthsSame( maTableBorder, bRangeIsSingleCell ))
496 if (maTableBorder.TopLine.LineDistance != 0)
498 aLinestyle = XlLineStyle::xlDouble;
500 else if ( maTableBorder.TopLine.OuterLineWidth != 0 )
502 aLinestyle = XlLineStyle::xlContinuous;
505 return uno::makeAny( aLinestyle );
507 void SAL_CALL ScVbaBorders::setLineStyle( const uno::Any& _linestyle ) throw (uno::RuntimeException, std::exception)
509 sal_Int32 count = getCount();
510 for( sal_Int32 i = 0; i < count ; i++ )
512 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
513 xBorder->setLineStyle( _linestyle );
516 uno::Any SAL_CALL ScVbaBorders::getWeight() throw (uno::RuntimeException, std::exception)
518 sal_Int32 count = getCount();
519 uno::Any weight;
520 for( sal_Int32 i = 0; i < count ; i++ )
522 if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
524 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
525 if( weight.hasValue() )
527 if( weight != xBorder->getWeight() )
528 return uno::makeAny( uno::Reference< uno::XInterface >() );
530 else
531 weight = xBorder->getWeight();
534 return weight;
536 void SAL_CALL ScVbaBorders::setWeight( const uno::Any& _weight ) throw (uno::RuntimeException, std::exception)
538 sal_Int32 count = getCount();
539 for( sal_Int32 i = 0; i < count ; i++ )
541 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
542 xBorder->setWeight( _weight );
546 OUString
547 ScVbaBorders::getServiceImplName()
549 return OUString("ScVbaBorders");
552 uno::Sequence< OUString >
553 ScVbaBorders::getServiceNames()
555 static uno::Sequence< OUString > aServiceNames;
556 if ( aServiceNames.getLength() == 0 )
558 aServiceNames.realloc( 1 );
559 aServiceNames[ 0 ] = "ooo.vba.excel.Borders";
561 return aServiceNames;
564 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */