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 .
20 #include <ooo/vba/excel/XRange.hpp>
21 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
22 #include <com/sun/star/sheet/XSheetConditionalEntry.hpp>
23 #include <cppuhelper/exc_hlp.hxx>
25 #include "unonames.hxx"
26 #include "vbaformatconditions.hxx"
27 #include "vbaformatcondition.hxx"
28 #include "vbaworkbook.hxx"
29 #include "vbastyles.hxx"
30 #include "vbaglobals.hxx"
31 using namespace ::ooo::vba
;
32 using namespace ::com::sun::star
;
34 typedef std::vector
< beans::PropertyValue
> VecPropValues
;
36 static const char OPERATOR
[] = "Operator";
37 static const char FORMULA1
[] = "Formula1";
38 static const char FORMULA2
[] = "Formula2";
39 static const char STYLENAME
[] = "StyleName";
40 static const char sStyleNamePrefix
[] = "Excel_CondFormat";
43 ScVbaFormatConditions::Delete( ) throw (script::BasicErrorException
, uno::RuntimeException
, std::exception
)
47 ScVbaStyles
* pStyles
= static_cast< ScVbaStyles
* >( mxStyles
.get() );
49 DebugHelper::basicexception(SbERR_METHOD_FAILED
, OUString() );
50 sal_Int32 nCount
= mxSheetConditionalEntries
->getCount();
51 for (sal_Int32 i
= nCount
- 1; i
>= 0; i
--)
53 uno::Reference
< sheet::XSheetConditionalEntry
> xSheetConditionalEntry( mxSheetConditionalEntries
->getByIndex(i
), uno::UNO_QUERY_THROW
);
54 pStyles
->Delete(xSheetConditionalEntry
->getStyleName());
55 mxSheetConditionalEntries
->removeByIndex(i
);
59 catch (uno::Exception
& )
61 DebugHelper::basicexception(SbERR_METHOD_FAILED
, OUString());
66 ScVbaFormatConditions::getElementType() throw (css::uno::RuntimeException
)
68 return cppu::UnoType
<excel::XFormatCondition
>::get();
71 static 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
)
73 uno::Reference
< sheet::XSheetConditionalEntry
> xSheetConditionalEntry
;
74 aObject
>>= xSheetConditionalEntry
;
76 uno::Reference
< excel::XStyle
> xStyle( xStyles
->Item( uno::makeAny( xSheetConditionalEntry
->getStyleName() ), uno::Any() ), uno::UNO_QUERY_THROW
);
77 uno::Reference
< excel::XFormatCondition
> xCondition
= new ScVbaFormatCondition( xRangeParent
, xContext
, xSheetConditionalEntry
, xStyle
, xFormatConditions
, xRangeProps
);
78 return uno::makeAny( xCondition
);
82 ScVbaFormatConditions::createCollectionObject(const uno::Any
& aObject
)
84 return xSheetConditionToFormatCondition( uno::Reference
< XHelperInterface
>( mxRangeParent
, uno::UNO_QUERY_THROW
), mxContext
, mxStyles
, this, mxParentRangePropertySet
, aObject
);
89 class EnumWrapper
: public EnumerationHelper_BASE
91 uno::Reference
<container::XIndexAccess
> m_xIndexAccess
;
92 uno::Reference
<excel::XRange
> m_xParentRange
;
93 uno::Reference
<uno::XComponentContext
> m_xContext
;
94 uno::Reference
<excel::XStyles
> m_xStyles
;
95 uno::Reference
<excel::XFormatConditions
> m_xParentCollection
;
96 uno::Reference
<beans::XPropertySet
> m_xProps
;
100 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 ) {}
101 virtual sal_Bool SAL_CALL
hasMoreElements( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
103 return ( nIndex
< m_xIndexAccess
->getCount() );
106 virtual uno::Any SAL_CALL
nextElement( ) throw (container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
, std::exception
) SAL_OVERRIDE
110 if ( nIndex
< m_xIndexAccess
->getCount() )
111 return xSheetConditionToFormatCondition( uno::Reference
< XHelperInterface
>( m_xParentRange
, uno::UNO_QUERY_THROW
), m_xContext
, m_xStyles
, m_xParentCollection
, m_xProps
, m_xIndexAccess
->getByIndex( nIndex
++ ) );
113 catch (const container::NoSuchElementException
&)
117 catch (const lang::WrappedTargetException
&)
121 catch (const uno::RuntimeException
&)
125 catch (const uno::Exception
& e
)
127 css::uno::Any
a(cppu::getCaughtException());
128 throw css::lang::WrappedTargetException(
129 "wrapped Exception " + e
.Message
,
130 css::uno::Reference
<css::uno::XInterface
>(), a
);
132 throw container::NoSuchElementException();
138 uno::Reference
< excel::XFormatCondition
> SAL_CALL
139 ScVbaFormatConditions::Add( ::sal_Int32 _nType
, const uno::Any
& _aOperator
, const uno::Any
& _aFormula1
, const uno::Any
& _aFormula2
) throw (script::BasicErrorException
, uno::RuntimeException
, std::exception
)
141 return Add( _nType
, _aOperator
, _aFormula1
, _aFormula2
, uno::Reference
< excel::XStyle
>() );
144 uno::Reference
< excel::XFormatCondition
>
145 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
)
149 // This method will NOT handle r1c1 formulas [*]and only assumes that
150 // the formulas are _xlA1 based ( need to hook into calc work this should
152 // [*] reason: getA1Formula method below is just a hook and just
153 // returns whats it gets ( e.g. doesn't convert anything )
154 uno::Reference
< excel::XStyle
> xStyle( _xStyle
);
155 uno::Reference
< excel::XFormatCondition
> xFormatCondition
;
161 sStyleName
= getStyleName();
162 xStyle
= mxStyles
->Add(sStyleName
, uno::Any() );
166 sStyleName
= xStyle
->getName();
169 VecPropValues aPropertyValueVector
;
170 sheet::ConditionOperator aType
= ScVbaFormatCondition::retrieveAPIType(_nType
, uno::Reference
< sheet::XSheetCondition
>() );
173 if ( aType
== sheet::ConditionOperator_FORMULA
)
174 aValue
= uno::makeAny( sheet::ConditionOperator_FORMULA
);
176 aValue
= uno::makeAny( ScVbaFormatCondition::retrieveAPIOperator(_aOperator
) );
178 beans::PropertyValue
aProperty( OPERATOR
, 0, aValue
, beans::PropertyState_DIRECT_VALUE
);
179 aPropertyValueVector
.push_back( aProperty
);
181 if ( _aFormula1
.hasValue() )
183 beans::PropertyValue
aProp( FORMULA1
, 0, uno::makeAny( getA1Formula( _aFormula1
) ), beans::PropertyState_DIRECT_VALUE
);
184 aPropertyValueVector
.push_back( aProp
);
186 if ( _aFormula2
.hasValue() )
188 beans::PropertyValue
aProp( FORMULA2
, 0, uno::makeAny( getA1Formula( _aFormula2
) ), beans::PropertyState_DIRECT_VALUE
);
189 aPropertyValueVector
.push_back( aProp
);
191 aProperty
.Name
= STYLENAME
;
192 aProperty
.Value
= uno::makeAny( sStyleName
);
194 // convert vector to sequence
195 uno::Sequence
< beans::PropertyValue
> aPropertyValueList(aPropertyValueVector
.size());
196 VecPropValues::iterator it
= aPropertyValueVector
.begin();
197 VecPropValues::iterator it_end
= aPropertyValueVector
.end();
198 for ( sal_Int32 index
=0; it
!= it_end
; ++it
)
199 aPropertyValueList
[ index
++ ] = *it
;
201 mxSheetConditionalEntries
->addNew(aPropertyValueList
);
202 for (sal_Int32 i
= mxSheetConditionalEntries
->getCount()-1; i
>= 0; i
--)
204 uno::Reference
< sheet::XSheetConditionalEntry
> xSheetConditionalEntry( mxSheetConditionalEntries
->getByIndex(i
), uno::UNO_QUERY_THROW
);
205 if (xSheetConditionalEntry
->getStyleName().equals(sStyleName
))
207 xFormatCondition
= new ScVbaFormatCondition(uno::Reference
< XHelperInterface
>( mxRangeParent
, uno::UNO_QUERY_THROW
), mxContext
, xSheetConditionalEntry
, xStyle
, this, mxParentRangePropertySet
);
209 return xFormatCondition
;
213 catch (uno::Exception
& )
216 DebugHelper::basicexception(SbERR_METHOD_FAILED
, OUString() );
217 return xFormatCondition
;
220 uno::Reference
< container::XEnumeration
> SAL_CALL
221 ScVbaFormatConditions::createEnumeration() throw (uno::RuntimeException
)
223 return new EnumWrapper( m_xIndexAccess
, mxRangeParent
, mxContext
, mxStyles
, this, mxParentRangePropertySet
);
227 ScVbaFormatConditions::notifyRange() throw ( script::BasicErrorException
)
231 mxParentRangePropertySet
->setPropertyValue(SC_UNONAME_CONDFMT
, uno::makeAny( mxSheetConditionalEntries
));
233 catch (uno::Exception
& )
235 DebugHelper::basicexception(SbERR_METHOD_FAILED
, OUString());
240 ScVbaFormatConditions::getA1Formula(const css::uno::Any
& _aFormula
) throw ( script::BasicErrorException
)
242 // #TODO, #FIXME hook-in proper formula conversion detection & logic
244 if ( !( _aFormula
>>= sFormula
) )
245 DebugHelper::basicexception(SbERR_BAD_PARAMETER
, OUString() );
250 ScVbaFormatConditions::getStyleName()
252 ScVbaStyles
* pStyles
= static_cast< ScVbaStyles
* >( mxStyles
.get() );
254 DebugHelper::basicexception(SbERR_METHOD_FAILED
, OUString() );
255 uno::Sequence
< OUString
> sCellStyleNames
= pStyles
->getStyleNames();
256 return ContainerUtilities::getUniqueName(sCellStyleNames
, sStyleNamePrefix
, OUString("_"));
260 ScVbaFormatConditions::removeFormatCondition( const OUString
& _sStyleName
, bool _bRemoveStyle
) throw ( script::BasicErrorException
)
264 sal_Int32 nElems
= mxSheetConditionalEntries
->getCount();
265 for (sal_Int32 i
= 0; i
< nElems
; i
++)
267 uno::Reference
< sheet::XSheetConditionalEntry
> xSheetConditionalEntry( mxSheetConditionalEntries
->getByIndex(i
), uno::UNO_QUERY_THROW
);
268 if (_sStyleName
.equals(xSheetConditionalEntry
->getStyleName()))
270 mxSheetConditionalEntries
->removeByIndex(i
);
273 ScVbaStyles
* pStyles
= static_cast< ScVbaStyles
* >( mxStyles
.get() );
275 DebugHelper::basicexception(SbERR_METHOD_FAILED
, OUString());
276 pStyles
->Delete( _sStyleName
);
282 catch (const uno::Exception
&)
284 DebugHelper::basicexception(SbERR_METHOD_FAILED
, OUString());
289 ScVbaFormatConditions::getServiceImplName()
291 return OUString("ScVbaFormatConditions");
294 uno::Sequence
< OUString
>
295 ScVbaFormatConditions::getServiceNames()
297 static uno::Sequence
< OUString
> aServiceNames
;
298 if ( aServiceNames
.getLength() == 0 )
300 aServiceNames
.realloc( 1 );
301 aServiceNames
[ 0 ] = "ooo.vba.excel.FormatConditions";
303 return aServiceNames
;
306 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */