GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / sc / source / ui / vba / vbaborders.cxx
blob15e695a99dd03987ac2e32c5a5f58d5c797e1db6
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;
38 typedef ::cppu::WeakImplHelper1<container::XIndexAccess > RangeBorders_Base;
39 typedef InheritedHelperInterfaceImpl1<excel::XBorder > ScVbaBorder_Base;
41 // #TODO sort these indexes to match the order in which Excel iterates over the
42 // borders, the enumeration will match the order in this list
43 static const sal_Int16 supportedIndexTable[] = { XlBordersIndex::xlEdgeLeft, XlBordersIndex::xlEdgeTop, XlBordersIndex::xlEdgeBottom, XlBordersIndex::xlEdgeRight, XlBordersIndex::xlDiagonalDown, XlBordersIndex::xlDiagonalUp, XlBordersIndex::xlInsideVertical, XlBordersIndex::xlInsideHorizontal };
45 const static OUString sTableBorder("TableBorder");
47 // Equiv widths in in 1/100 mm
48 const static sal_Int32 OOLineThin = 35;
49 const static sal_Int32 OOLineMedium = 88;
50 const static sal_Int32 OOLineThick = 141;
51 const static sal_Int32 OOLineHairline = 2;
53 class ScVbaBorder : public ScVbaBorder_Base
55 private:
56 uno::Reference< beans::XPropertySet > m_xProps;
57 sal_Int32 m_LineType;
58 ScVbaPalette m_Palette;
59 bool setBorderLine( table::BorderLine& rBorderLine )
61 table::TableBorder aTableBorder;
62 m_xProps->getPropertyValue( sTableBorder ) >>= aTableBorder;
64 switch ( m_LineType )
66 case XlBordersIndex::xlEdgeLeft:
67 aTableBorder.IsLeftLineValid = sal_True;
68 aTableBorder.LeftLine= rBorderLine;
69 break;
70 case XlBordersIndex::xlEdgeTop:
71 aTableBorder.IsTopLineValid = sal_True;
72 aTableBorder.TopLine = rBorderLine;
73 break;
75 case XlBordersIndex::xlEdgeBottom:
76 aTableBorder.IsBottomLineValid = sal_True;
77 aTableBorder.BottomLine = rBorderLine;
78 break;
79 case XlBordersIndex::xlEdgeRight:
80 aTableBorder.IsRightLineValid = sal_True;
81 aTableBorder.RightLine = rBorderLine;
82 break;
83 case XlBordersIndex::xlInsideVertical:
84 aTableBorder.IsVerticalLineValid = sal_True;
85 aTableBorder.VerticalLine = rBorderLine;
86 break;
87 case XlBordersIndex::xlInsideHorizontal:
88 aTableBorder.IsHorizontalLineValid = sal_True;
89 aTableBorder.HorizontalLine = rBorderLine;
90 break;
91 case XlBordersIndex::xlDiagonalDown:
92 case XlBordersIndex::xlDiagonalUp:
93 // #TODO have to ignore at the momement, would be
94 // nice to investigate what we can do here
95 break;
96 default:
97 return false;
99 m_xProps->setPropertyValue( sTableBorder, uno::makeAny(aTableBorder) );
100 return true;
103 bool getBorderLine( table::BorderLine& rBorderLine )
105 table::TableBorder aTableBorder;
106 m_xProps->getPropertyValue( sTableBorder ) >>= aTableBorder;
107 switch ( m_LineType )
109 case XlBordersIndex::xlEdgeLeft:
110 if ( aTableBorder.IsLeftLineValid )
111 rBorderLine = aTableBorder.LeftLine;
112 break;
113 case XlBordersIndex::xlEdgeTop:
114 if ( aTableBorder.IsTopLineValid )
115 rBorderLine = aTableBorder.TopLine;
116 break;
118 case XlBordersIndex::xlEdgeBottom:
119 if ( aTableBorder.IsBottomLineValid )
120 rBorderLine = aTableBorder.BottomLine;
121 break;
122 case XlBordersIndex::xlEdgeRight:
123 if ( aTableBorder.IsRightLineValid )
124 rBorderLine = aTableBorder.RightLine;
125 break;
126 case XlBordersIndex::xlInsideVertical:
127 if ( aTableBorder.IsVerticalLineValid )
128 rBorderLine = aTableBorder.VerticalLine;
129 break;
130 case XlBordersIndex::xlInsideHorizontal:
131 if ( aTableBorder.IsHorizontalLineValid )
132 rBorderLine = aTableBorder.HorizontalLine;
133 break;
135 case XlBordersIndex::xlDiagonalDown:
136 case XlBordersIndex::xlDiagonalUp:
137 // #TODO have to ignore at the momement, would be
138 // nice to investigate what we can do here
139 break;
140 default:
141 return false;
143 return true;
145 ScVbaBorder(); // no impl
146 protected:
147 virtual OUString getServiceImplName()
149 return OUString("ScVbaBorder");
151 virtual css::uno::Sequence<OUString> getServiceNames()
153 static uno::Sequence< OUString > aServiceNames;
154 if ( aServiceNames.getLength() == 0 )
156 aServiceNames.realloc( 1 );
157 aServiceNames[ 0 ] = "ooo.vba.excel.Border";
159 return aServiceNames;
161 public:
162 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 ) {}
164 // XBorder
165 uno::Any SAL_CALL getColor() throw (uno::RuntimeException)
167 table::BorderLine aBorderLine;
168 if ( getBorderLine( aBorderLine ) )
169 return uno::makeAny( OORGBToXLRGB( aBorderLine.Color ) );
170 throw uno::RuntimeException("No Implementation available", uno::Reference< uno::XInterface >() );
172 void SAL_CALL setColor( const uno::Any& _color ) throw (uno::RuntimeException)
174 sal_Int32 nColor = 0;
175 _color >>= nColor;
176 table::BorderLine aBorderLine;
177 if ( getBorderLine( aBorderLine ) )
179 aBorderLine.Color = XLRGBToOORGB( nColor );
180 setBorderLine( aBorderLine );
182 else
183 throw uno::RuntimeException("No Implementation available", uno::Reference< uno::XInterface >() );
186 uno::Any SAL_CALL getColorIndex() throw (uno::RuntimeException)
188 sal_Int32 nColor = 0;
189 XLRGBToOORGB( getColor() ) >>= nColor;
190 uno::Reference< container::XIndexAccess > xIndex = m_Palette.getPalette();
191 sal_Int32 nElems = xIndex->getCount();
192 sal_Int32 nIndex = -1;
193 for ( sal_Int32 count=0; count<nElems; ++count )
195 sal_Int32 nPaletteColor = 0;
196 xIndex->getByIndex( count ) >>= nPaletteColor;
197 if ( nPaletteColor == nColor )
199 nIndex = count + 1;
200 break;
203 return uno::makeAny(nIndex);
206 void SAL_CALL setColorIndex( const uno::Any& _colorindex ) throw (uno::RuntimeException)
208 sal_Int32 nColor = 0;
209 _colorindex >>= nColor;
210 if ( !nColor || nColor == XlColorIndex::xlColorIndexAutomatic )
211 nColor = 1;
212 setColor( OORGBToXLRGB( m_Palette.getPalette()->getByIndex( --nColor ) ) );
214 uno::Any SAL_CALL getWeight() throw (uno::RuntimeException)
216 table::BorderLine aBorderLine;
217 if ( getBorderLine( aBorderLine ) )
219 switch ( aBorderLine.OuterLineWidth )
221 case 0: // Thin = default OO thickness
222 case OOLineThin:
223 return uno::makeAny( XlBorderWeight::xlThin );
224 case OOLineMedium:
225 return uno::makeAny( XlBorderWeight::xlMedium );
226 case OOLineThick:
227 return uno::makeAny( XlBorderWeight::xlThick );
228 case OOLineHairline:
229 return uno::makeAny( XlBorderWeight::xlHairline );
230 default:
231 break;
234 throw uno::RuntimeException("Method failed", uno::Reference< uno::XInterface >() );
236 void SAL_CALL setWeight( const uno::Any& _weight ) throw (uno::RuntimeException)
238 sal_Int32 nWeight = 0;
239 _weight >>= nWeight;
240 table::BorderLine aBorderLine;
241 if ( getBorderLine( aBorderLine ) )
243 switch ( nWeight )
245 case XlBorderWeight::xlThin:
246 aBorderLine.OuterLineWidth = OOLineThin;
247 break;
248 case XlBorderWeight::xlMedium:
249 aBorderLine.OuterLineWidth = OOLineMedium;
250 break;
251 case XlBorderWeight::xlThick:
252 aBorderLine.OuterLineWidth = OOLineThick;
253 break;
254 case XlBorderWeight::xlHairline:
255 aBorderLine.OuterLineWidth = OOLineHairline;
256 break;
257 default:
258 throw uno::RuntimeException("Bad param", uno::Reference< uno::XInterface >() );
260 setBorderLine( aBorderLine );
262 else
263 throw uno::RuntimeException("Method failed", uno::Reference< uno::XInterface >() );
266 uno::Any SAL_CALL getLineStyle() throw (uno::RuntimeException)
268 // always return xlContinuous;
269 return uno::makeAny( XlLineStyle::xlContinuous );
271 void SAL_CALL setLineStyle( const uno::Any& _linestyle ) throw (uno::RuntimeException)
273 // Urk no choice but to silently ignore we don't support this attribute
274 // #TODO would be nice to support the excel line styles
275 sal_Int32 nLineStyle = 0;
276 _linestyle >>= nLineStyle;
277 table::BorderLine aBorderLine;
278 if ( getBorderLine( aBorderLine ) )
280 switch ( nLineStyle )
282 case XlLineStyle::xlContinuous:
283 case XlLineStyle::xlDash:
284 case XlLineStyle::xlDashDot:
285 case XlLineStyle::xlDashDotDot:
286 case XlLineStyle::xlDot:
287 case XlLineStyle::xlDouble:
288 case XlLineStyle::xlLineStyleNone:
289 case XlLineStyle::xlSlantDashDot:
290 break;
291 default:
292 throw uno::RuntimeException("Bad param", uno::Reference< uno::XInterface >() );
294 setBorderLine( aBorderLine );
296 else
297 throw uno::RuntimeException("Method failed", uno::Reference< uno::XInterface >() );
301 class RangeBorders : public RangeBorders_Base
303 private:
304 uno::Reference< table::XCellRange > m_xRange;
305 uno::Reference< uno::XComponentContext > m_xContext;
306 ScVbaPalette m_Palette;
307 sal_Int32 getTableIndex( sal_Int32 nConst )
309 // hokay return position of the index in the table
310 sal_Int32 nIndexes = getCount();
311 sal_Int32 realIndex = 0;
312 const sal_Int16* pTableEntry = supportedIndexTable;
313 for ( ; realIndex < nIndexes; ++realIndex, ++pTableEntry )
315 if ( *pTableEntry == nConst )
316 return realIndex;
318 return getCount(); // error condition
320 public:
321 RangeBorders( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, ScVbaPalette& rPalette ) : m_xRange( xRange ), m_xContext( xContext ), m_Palette( rPalette )
324 // XIndexAccess
325 virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException)
327 return sizeof( supportedIndexTable ) / sizeof( supportedIndexTable[0] );
329 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
332 sal_Int32 nIndex = getTableIndex( Index );
333 if ( nIndex >= 0 && nIndex < getCount() )
335 uno::Reference< beans::XPropertySet > xProps( m_xRange, uno::UNO_QUERY_THROW );
336 return uno::makeAny( uno::Reference< excel::XBorder >( new ScVbaBorder( xProps, m_xContext, supportedIndexTable[ nIndex ], m_Palette )) );
338 throw lang::IndexOutOfBoundsException();
340 virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException)
342 return excel::XBorder::static_type(0);
344 virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException)
346 return sal_True;
350 uno::Reference< container::XIndexAccess >
351 rangeToBorderIndexAccess( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< uno::XComponentContext > & xContext, ScVbaPalette& rPalette )
353 return new RangeBorders( xRange, xContext, rPalette );
356 class RangeBorderEnumWrapper : public EnumerationHelper_BASE
358 uno::Reference<container::XIndexAccess > m_xIndexAccess;
359 sal_Int32 nIndex;
360 public:
361 RangeBorderEnumWrapper( const uno::Reference< container::XIndexAccess >& xIndexAccess ) : m_xIndexAccess( xIndexAccess ), nIndex( 0 ) {}
362 virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
364 return ( nIndex < m_xIndexAccess->getCount() );
367 virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
369 if ( nIndex < m_xIndexAccess->getCount() )
370 return m_xIndexAccess->getByIndex( nIndex++ );
371 throw container::NoSuchElementException();
375 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 )
377 uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, uno::UNO_QUERY_THROW );
378 if ( xColumnRowRange->getRows()->getCount() == 1 && xColumnRowRange->getColumns()->getCount() == 1 )
379 bRangeIsSingleCell = true;
380 m_xProps.set( xRange, uno::UNO_QUERY_THROW );
383 uno::Reference< container::XEnumeration >
384 ScVbaBorders::createEnumeration() throw (uno::RuntimeException)
386 return new RangeBorderEnumWrapper( m_xIndexAccess );
389 uno::Any
390 ScVbaBorders::createCollectionObject( const css::uno::Any& aSource )
392 return aSource; // its already a Border object
395 uno::Type
396 ScVbaBorders::getElementType() throw (uno::RuntimeException)
398 return excel::XBorders::static_type(0);
401 uno::Any
402 ScVbaBorders::getItemByIntIndex( const sal_Int32 nIndex ) throw (uno::RuntimeException)
404 return createCollectionObject( m_xIndexAccess->getByIndex( nIndex ) );
408 uno::Any SAL_CALL ScVbaBorders::getColor() throw (uno::RuntimeException)
410 sal_Int32 count = getCount();
411 uno::Any color;
412 for( sal_Int32 i = 0; i < count ; i++ )
414 if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
416 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
417 if( color.hasValue() )
419 if( color != xBorder->getColor() )
420 return uno::makeAny( uno::Reference< uno::XInterface >() );
422 else
423 color = xBorder->getColor();
426 return color;
428 void SAL_CALL ScVbaBorders::setColor( const uno::Any& _color ) throw (uno::RuntimeException)
430 sal_Int32 count = getCount();
431 for( sal_Int32 i = 0; i < count ; i++ )
433 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
434 xBorder->setColor( _color );
437 uno::Any SAL_CALL ScVbaBorders::getColorIndex() throw (uno::RuntimeException)
439 sal_Int32 count = getCount();
440 uno::Any nColorIndex;
441 for( sal_Int32 i = 0; i < count ; i++ )
443 if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
445 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
446 if( nColorIndex.hasValue() )
448 if( nColorIndex != xBorder->getColorIndex() )
449 return uno::makeAny( uno::Reference< uno::XInterface >() );
451 else
452 nColorIndex = xBorder->getColorIndex();
455 return nColorIndex;
457 void SAL_CALL ScVbaBorders::setColorIndex( const uno::Any& _colorindex ) throw (uno::RuntimeException)
459 sal_Int32 count = getCount();
460 for( sal_Int32 i = 0; i < count ; i++ )
462 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
463 xBorder->setColorIndex( _colorindex );
467 static bool
468 lcl_areAllLineWidthsSame( const table::TableBorder& maTableBorder, bool bIsCell )
471 bool bRes = false;
472 if (bIsCell)
474 bRes = ((maTableBorder.TopLine.OuterLineWidth == maTableBorder.BottomLine.OuterLineWidth) &&
475 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.LeftLine.OuterLineWidth) &&
476 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.RightLine.OuterLineWidth));
478 else
480 bRes = ((maTableBorder.TopLine.OuterLineWidth == maTableBorder.BottomLine.OuterLineWidth) &&
481 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.LeftLine.OuterLineWidth) &&
482 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.HorizontalLine.OuterLineWidth) &&
483 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.VerticalLine.OuterLineWidth) &&
484 (maTableBorder.TopLine.OuterLineWidth == maTableBorder.RightLine.OuterLineWidth));
486 return bRes;
489 uno::Any SAL_CALL ScVbaBorders::getLineStyle() throw (uno::RuntimeException)
491 table::TableBorder maTableBorder;
492 m_xProps->getPropertyValue( sTableBorder ) >>= maTableBorder;
494 sal_Int32 aLinestyle = XlLineStyle::xlLineStyleNone;
496 if ( lcl_areAllLineWidthsSame( maTableBorder, bRangeIsSingleCell ))
498 if (maTableBorder.TopLine.LineDistance != 0)
500 aLinestyle = XlLineStyle::xlDouble;
502 else if ( maTableBorder.TopLine.OuterLineWidth != 0 )
504 aLinestyle = XlLineStyle::xlContinuous;
507 return uno::makeAny( aLinestyle );
509 void SAL_CALL ScVbaBorders::setLineStyle( const uno::Any& _linestyle ) throw (uno::RuntimeException)
511 sal_Int32 count = getCount();
512 for( sal_Int32 i = 0; i < count ; i++ )
514 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
515 xBorder->setLineStyle( _linestyle );
518 uno::Any SAL_CALL ScVbaBorders::getWeight() throw (uno::RuntimeException)
520 sal_Int32 count = getCount();
521 uno::Any weight;
522 for( sal_Int32 i = 0; i < count ; i++ )
524 if( XlBordersIndex::xlDiagonalDown != supportedIndexTable[i] && XlBordersIndex::xlDiagonalUp != supportedIndexTable[i] )
526 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
527 if( weight.hasValue() )
529 if( weight != xBorder->getWeight() )
530 return uno::makeAny( uno::Reference< uno::XInterface >() );
532 else
533 weight = xBorder->getWeight();
536 return weight;
538 void SAL_CALL ScVbaBorders::setWeight( const uno::Any& _weight ) throw (uno::RuntimeException)
540 sal_Int32 count = getCount();
541 for( sal_Int32 i = 0; i < count ; i++ )
543 uno::Reference< XBorder > xBorder( getItemByIntIndex( supportedIndexTable[i] ), uno::UNO_QUERY_THROW );
544 xBorder->setWeight( _weight );
549 OUString
550 ScVbaBorders::getServiceImplName()
552 return OUString("ScVbaBorders");
555 uno::Sequence< OUString >
556 ScVbaBorders::getServiceNames()
558 static uno::Sequence< OUString > aServiceNames;
559 if ( aServiceNames.getLength() == 0 )
561 aServiceNames.realloc( 1 );
562 aServiceNames[ 0 ] = "ooo.vba.excel.Borders";
564 return aServiceNames;
567 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */