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: vbaformatconditions.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 ************************************************************************/
31 #include <ooo/vba/excel/XRange.hpp>
32 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
33 #include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
35 #include "vbaformatconditions.hxx"
36 #include "vbaformatcondition.hxx"
37 #include "vbaworkbook.hxx"
38 #include "vbastyles.hxx"
39 #include "vbaglobals.hxx"
40 using namespace ::ooo::vba
;
41 using namespace ::com::sun::star
;
43 typedef std::vector
< beans::PropertyValue
> VecPropValues
;
45 static rtl::OUString
OPERATOR( RTL_CONSTASCII_USTRINGPARAM("Operator") );
46 static rtl::OUString
FORMULA1( RTL_CONSTASCII_USTRINGPARAM("Formula1") );
47 static rtl::OUString
FORMULA2( RTL_CONSTASCII_USTRINGPARAM("Formula2") );
48 static rtl::OUString
STYLENAME( RTL_CONSTASCII_USTRINGPARAM("StyleName") );
49 static rtl::OUString
sStyleNamePrefix( RTL_CONSTASCII_USTRINGPARAM("Excel_CondFormat") );
51 ScVbaFormatConditions::ScVbaFormatConditions( const uno::Reference
< XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
> & xContext
, const uno::Reference
< sheet::XSheetConditionalEntries
>& _xSheetConditionalEntries
, const uno::Reference
< frame::XModel
>& xModel
) : ScVbaFormatConditions_BASE( xParent
, xContext
, uno::Reference
< container::XIndexAccess
>( _xSheetConditionalEntries
, uno::UNO_QUERY_THROW
) ), mxSheetConditionalEntries( _xSheetConditionalEntries
)
53 mxRangeParent
.set( xParent
, uno::UNO_QUERY_THROW
);
54 uno::Reference
< excel::XWorkbook
> xWorkbook
= new ScVbaWorkbook( uno::Reference
< XHelperInterface
>( Application(), uno::UNO_QUERY_THROW
), xContext
, xModel
);
55 mxStyles
.set( xWorkbook
->Styles( uno::Any() ), uno::UNO_QUERY_THROW
);
56 uno::Reference
< sheet::XCellRangeAddressable
> xCellRange( mxRangeParent
->getCellRange(), uno::UNO_QUERY_THROW
);
57 mxParentRangePropertySet
.set( xCellRange
, uno::UNO_QUERY_THROW
);
59 table::CellRangeAddress rangeAddress
= xCellRange
->getRangeAddress();
60 maCellAddress
= table::CellAddress( rangeAddress
.Sheet
, rangeAddress
.StartColumn
, rangeAddress
.StartRow
);
64 ScVbaFormatConditions::Delete( ) throw (script::BasicErrorException
, uno::RuntimeException
)
68 ScVbaStyles
* pStyles
= static_cast< ScVbaStyles
* >( mxStyles
.get() );
70 DebugHelper::exception(SbERR_METHOD_FAILED
, rtl::OUString() );
71 sal_Int32 nCount
= mxSheetConditionalEntries
->getCount();
72 for (sal_Int32 i
= nCount
- 1; i
>= 0; i
--)
74 uno::Reference
< sheet::XSheetConditionalEntry
> xSheetConditionalEntry( mxSheetConditionalEntries
->getByIndex(i
), uno::UNO_QUERY_THROW
);
75 pStyles
->Delete(xSheetConditionalEntry
->getStyleName());
76 mxSheetConditionalEntries
->removeByIndex(i
);
80 catch (uno::Exception
& )
82 DebugHelper::exception(SbERR_METHOD_FAILED
, rtl::OUString());
87 ScVbaFormatConditions::getElementType() throw (css::uno::RuntimeException
)
89 return excel::XFormatCondition::static_type(0);
93 uno::Any
xSheetConditionToFormatCondition( const uno::Reference
< XHelperInterface
>& xRangeParent
, const uno::Reference
< uno::XComponentContext
>& xContext
, const uno::Reference
< excel::XStyles
>& xStyles
, const uno::Reference
< excel::XFormatConditions
>& xFormatConditions
, const uno::Reference
< beans::XPropertySet
>& xRangeProps
, const uno::Any
& aObject
)
95 uno::Reference
< sheet::XSheetConditionalEntry
> xSheetConditionalEntry
;
96 aObject
>>= xSheetConditionalEntry
;
98 uno::Reference
< excel::XStyle
> xStyle( xStyles
->Item( uno::makeAny( xSheetConditionalEntry
->getStyleName() ), uno::Any() ), uno::UNO_QUERY_THROW
);
99 uno::Reference
< excel::XFormatCondition
> xCondition
= new ScVbaFormatCondition( xRangeParent
, xContext
, xSheetConditionalEntry
, xStyle
, xFormatConditions
, xRangeProps
);
100 return uno::makeAny( xCondition
);
104 ScVbaFormatConditions::createCollectionObject(const uno::Any
& aObject
)
106 return xSheetConditionToFormatCondition( uno::Reference
< XHelperInterface
>( mxRangeParent
, uno::UNO_QUERY_THROW
), mxContext
, mxStyles
, this, mxParentRangePropertySet
, aObject
);
109 class EnumWrapper
: public EnumerationHelper_BASE
111 uno::Reference
<container::XIndexAccess
> m_xIndexAccess
;
112 uno::Reference
<excel::XRange
> m_xParentRange
;
113 uno::Reference
<uno::XComponentContext
> m_xContext
;
114 uno::Reference
<excel::XStyles
> m_xStyles
;
115 uno::Reference
<excel::XFormatConditions
> m_xParentCollection
;
116 uno::Reference
<beans::XPropertySet
> m_xProps
;
120 EnumWrapper( const uno::Reference
< container::XIndexAccess
>& xIndexAccess
, const uno::Reference
<excel::XRange
>& xRange
, const uno::Reference
<uno::XComponentContext
>& xContext
, const uno::Reference
<excel::XStyles
>& xStyles
, const uno::Reference
< excel::XFormatConditions
>& xCollection
, const uno::Reference
<beans::XPropertySet
>& xProps
) : m_xIndexAccess( xIndexAccess
), m_xParentRange( xRange
), m_xContext( xContext
), m_xStyles( xStyles
), m_xParentCollection( xCollection
), m_xProps( xProps
), nIndex( 0 ) {}
121 virtual ::sal_Bool SAL_CALL
hasMoreElements( ) throw (uno::RuntimeException
)
123 return ( nIndex
< m_xIndexAccess
->getCount() );
126 virtual uno::Any SAL_CALL
nextElement( ) throw (container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
)
128 if ( nIndex
< m_xIndexAccess
->getCount() )
129 return xSheetConditionToFormatCondition( uno::Reference
< XHelperInterface
>( m_xParentRange
, uno::UNO_QUERY_THROW
), m_xContext
, m_xStyles
, m_xParentCollection
, m_xProps
, m_xIndexAccess
->getByIndex( nIndex
++ ) );
130 throw container::NoSuchElementException();
134 uno::Reference
< excel::XFormatCondition
> SAL_CALL
135 ScVbaFormatConditions::Add( ::sal_Int32 _nType
, const uno::Any
& _aOperator
, const uno::Any
& _aFormula1
, const uno::Any
& _aFormula2
) throw (script::BasicErrorException
, uno::RuntimeException
)
137 return Add( _nType
, _aOperator
, _aFormula1
, _aFormula2
, uno::Reference
< excel::XStyle
>() );
140 uno::Reference
< excel::XFormatCondition
>
141 ScVbaFormatConditions::Add( ::sal_Int32 _nType
, const uno::Any
& _aOperator
, const uno::Any
& _aFormula1
, const uno::Any
& _aFormula2
, const css::uno::Reference
< excel::XStyle
>& _xStyle
) throw (script::BasicErrorException
, uno::RuntimeException
)
145 // This method will NOT handle r1c1 formulas [*]and only assumes that
146 // the formulas are _xlA1 based ( need to hook into calc work ths should
148 // [*] reason: getA1Formula method below is just a hook and just
149 // returns whats it gets ( e.g. doesn't convert anything )
150 uno::Reference
< excel::XStyle
> xStyle( _xStyle
);
151 uno::Reference
< excel::XFormatCondition
> xFormatCondition
;
154 rtl::OUString sStyleName
;
157 sStyleName
= getStyleName();
158 xStyle
= mxStyles
->Add(sStyleName
, uno::Any() );
162 sStyleName
= xStyle
->getName();
165 VecPropValues aPropertyValueVector
;
166 sheet::ConditionOperator aType
= ScVbaFormatCondition::retrieveAPIType(_nType
, uno::Reference
< sheet::XSheetCondition
>() );
169 if ( aType
== sheet::ConditionOperator_FORMULA
)
170 aValue
= uno::makeAny( sheet::ConditionOperator_FORMULA
);
172 aValue
= uno::makeAny( ScVbaFormatCondition::retrieveAPIOperator(_aOperator
) );
174 beans::PropertyValue
aProperty( OPERATOR
, 0, aValue
, beans::PropertyState_DIRECT_VALUE
);
175 aPropertyValueVector
.push_back( aProperty
);
177 if ( _aFormula1
.hasValue() )
179 beans::PropertyValue
aProp( FORMULA1
, 0, uno::makeAny( getA1Formula( _aFormula1
) ), beans::PropertyState_DIRECT_VALUE
);
180 aPropertyValueVector
.push_back( aProp
);
182 if ( _aFormula2
.hasValue() )
184 beans::PropertyValue
aProp( FORMULA2
, 0, uno::makeAny( getA1Formula( _aFormula2
) ), beans::PropertyState_DIRECT_VALUE
);
185 aPropertyValueVector
.push_back( aProp
);
187 aProperty
.Name
= STYLENAME
;
188 aProperty
.Value
= uno::makeAny( sStyleName
);
190 // convert vector to sequence
191 uno::Sequence
< beans::PropertyValue
> aPropertyValueList(aPropertyValueVector
.size());
192 VecPropValues::iterator it
= aPropertyValueVector
.begin();
193 VecPropValues::iterator it_end
= aPropertyValueVector
.end();
194 for ( sal_Int32 index
=0; it
!= it_end
; ++it
)
195 aPropertyValueList
[ index
++ ] = *it
;
197 mxSheetConditionalEntries
->addNew(aPropertyValueList
);
198 for (sal_Int32 i
= mxSheetConditionalEntries
->getCount()-1; i
>= 0; i
--)
200 uno::Reference
< sheet::XSheetConditionalEntry
> xSheetConditionalEntry( mxSheetConditionalEntries
->getByIndex(i
), uno::UNO_QUERY_THROW
);
201 if (xSheetConditionalEntry
->getStyleName().equals(sStyleName
))
203 xFormatCondition
= new ScVbaFormatCondition(uno::Reference
< XHelperInterface
>( mxRangeParent
, uno::UNO_QUERY_THROW
), mxContext
, xSheetConditionalEntry
, xStyle
, this, mxParentRangePropertySet
);
205 return xFormatCondition
;
209 catch (uno::Exception
& )
212 DebugHelper::exception(SbERR_METHOD_FAILED
, rtl::OUString() );
213 return xFormatCondition
;
217 uno::Reference
< container::XEnumeration
> SAL_CALL
218 ScVbaFormatConditions::createEnumeration() throw (uno::RuntimeException
)
220 return new EnumWrapper( m_xIndexAccess
, mxRangeParent
, mxContext
, mxStyles
, this, mxParentRangePropertySet
);
225 ScVbaFormatConditions::notifyRange() throw ( script::BasicErrorException
)
229 mxParentRangePropertySet
->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ConditionalFormat")), uno::makeAny( mxSheetConditionalEntries
));
231 catch (uno::Exception
& )
233 DebugHelper::exception(SbERR_METHOD_FAILED
, rtl::OUString());
238 ScVbaFormatConditions::getA1Formula(const css::uno::Any
& _aFormula
) throw ( script::BasicErrorException
)
240 // #TODO, #FIXME hook-in proper formula conversion detection & logic
241 rtl::OUString sFormula
;
242 if ( !( _aFormula
>>= sFormula
) )
243 DebugHelper::exception(SbERR_BAD_PARAMETER
, rtl::OUString() );
248 ScVbaFormatConditions::getStyleName()
250 ScVbaStyles
* pStyles
= static_cast< ScVbaStyles
* >( mxStyles
.get() );
252 DebugHelper::exception(SbERR_METHOD_FAILED
, rtl::OUString() );
253 uno::Sequence
< rtl::OUString
> sCellStyleNames
= pStyles
->getStyleNames();
254 return ContainerUtilities::getUniqueName(sCellStyleNames
, sStyleNamePrefix
, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_") ));
258 ScVbaFormatConditions::removeFormatCondition( const rtl::OUString
& _sStyleName
, sal_Bool _bRemoveStyle
) throw ( script::BasicErrorException
)
262 sal_Int32 nElems
= mxSheetConditionalEntries
->getCount();
263 for (sal_Int32 i
= 0; i
< nElems
; i
++)
265 uno::Reference
< sheet::XSheetConditionalEntry
> xSheetConditionalEntry( mxSheetConditionalEntries
->getByIndex(i
), uno::UNO_QUERY_THROW
);
266 if (_sStyleName
.equals(xSheetConditionalEntry
->getStyleName()))
268 mxSheetConditionalEntries
->removeByIndex(i
);
271 ScVbaStyles
* pStyles
= static_cast< ScVbaStyles
* >( mxStyles
.get() );
273 DebugHelper::exception(SbERR_METHOD_FAILED
, rtl::OUString());
274 pStyles
->Delete( _sStyleName
);
280 catch (uno::Exception
& )
282 DebugHelper::exception(SbERR_METHOD_FAILED
, rtl::OUString());
287 ScVbaFormatConditions::getServiceImplName()
289 static rtl::OUString
sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaFormatConditions") );
293 uno::Sequence
< rtl::OUString
>
294 ScVbaFormatConditions::getServiceNames()
296 static uno::Sequence
< rtl::OUString
> aServiceNames
;
297 if ( aServiceNames
.getLength() == 0 )
299 aServiceNames
.realloc( 1 );
300 aServiceNames
[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.FormatConditions" ) );
302 return aServiceNames
;