1*b3f79822SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*b3f79822SAndrew Rist * distributed with this work for additional information 6*b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*b3f79822SAndrew Rist * "License"); you may not use this file except in compliance 9*b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*b3f79822SAndrew Rist * software distributed under the License is distributed on an 15*b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b3f79822SAndrew Rist * KIND, either express or implied. See the License for the 17*b3f79822SAndrew Rist * specific language governing permissions and limitations 18*b3f79822SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*b3f79822SAndrew Rist *************************************************************/ 21*b3f79822SAndrew Rist 22*b3f79822SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include <ooo/vba/excel/XRange.hpp> 25cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangeAddressable.hpp> 26cdf0e10cSrcweir #include <com/sun/star/sheet/XSheetConditionalEntry.hpp> 27cdf0e10cSrcweir #include <vector> 28cdf0e10cSrcweir #include "vbaformatconditions.hxx" 29cdf0e10cSrcweir #include "vbaformatcondition.hxx" 30cdf0e10cSrcweir #include "vbaworkbook.hxx" 31cdf0e10cSrcweir #include "vbastyles.hxx" 32cdf0e10cSrcweir #include "vbaglobals.hxx" 33cdf0e10cSrcweir using namespace ::ooo::vba; 34cdf0e10cSrcweir using namespace ::com::sun::star; 35cdf0e10cSrcweir 36cdf0e10cSrcweir typedef std::vector< beans::PropertyValue > VecPropValues; 37cdf0e10cSrcweir 38cdf0e10cSrcweir static rtl::OUString OPERATOR( RTL_CONSTASCII_USTRINGPARAM("Operator") ); 39cdf0e10cSrcweir static rtl::OUString FORMULA1( RTL_CONSTASCII_USTRINGPARAM("Formula1") ); 40cdf0e10cSrcweir static rtl::OUString FORMULA2( RTL_CONSTASCII_USTRINGPARAM("Formula2") ); 41cdf0e10cSrcweir static rtl::OUString STYLENAME( RTL_CONSTASCII_USTRINGPARAM("StyleName") ); 42cdf0e10cSrcweir static rtl::OUString sStyleNamePrefix( RTL_CONSTASCII_USTRINGPARAM("Excel_CondFormat") ); 43cdf0e10cSrcweir 44cdf0e10cSrcweir 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 ) 45cdf0e10cSrcweir { 46cdf0e10cSrcweir mxRangeParent.set( xParent, uno::UNO_QUERY_THROW ); 47cdf0e10cSrcweir uno::Reference< excel::XApplication> xApp( Application(), uno::UNO_QUERY_THROW ); 48cdf0e10cSrcweir mxStyles.set( xApp->getThisWorkbook()->Styles( uno::Any() ), uno::UNO_QUERY_THROW ); 49cdf0e10cSrcweir uno::Reference< sheet::XCellRangeAddressable > xCellRange( mxRangeParent->getCellRange(), uno::UNO_QUERY_THROW ); 50cdf0e10cSrcweir mxParentRangePropertySet.set( xCellRange, uno::UNO_QUERY_THROW ); 51cdf0e10cSrcweir 52cdf0e10cSrcweir table::CellRangeAddress rangeAddress = xCellRange->getRangeAddress(); 53cdf0e10cSrcweir maCellAddress = table::CellAddress( rangeAddress.Sheet, rangeAddress.StartColumn, rangeAddress.StartRow ); 54cdf0e10cSrcweir } 55cdf0e10cSrcweir 56cdf0e10cSrcweir void SAL_CALL 57cdf0e10cSrcweir ScVbaFormatConditions::Delete( ) throw (script::BasicErrorException, uno::RuntimeException) 58cdf0e10cSrcweir { 59cdf0e10cSrcweir try 60cdf0e10cSrcweir { 61cdf0e10cSrcweir ScVbaStyles* pStyles = static_cast< ScVbaStyles* >( mxStyles.get() ); 62cdf0e10cSrcweir if ( !pStyles ) 63cdf0e10cSrcweir DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() ); 64cdf0e10cSrcweir sal_Int32 nCount = mxSheetConditionalEntries->getCount(); 65cdf0e10cSrcweir for (sal_Int32 i = nCount - 1; i >= 0; i--) 66cdf0e10cSrcweir { 67cdf0e10cSrcweir uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry( mxSheetConditionalEntries->getByIndex(i), uno::UNO_QUERY_THROW ); 68cdf0e10cSrcweir pStyles->Delete(xSheetConditionalEntry->getStyleName()); 69cdf0e10cSrcweir mxSheetConditionalEntries->removeByIndex(i); 70cdf0e10cSrcweir } 71cdf0e10cSrcweir notifyRange(); 72cdf0e10cSrcweir } 73cdf0e10cSrcweir catch (uno::Exception& ) 74cdf0e10cSrcweir { 75cdf0e10cSrcweir DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString()); 76cdf0e10cSrcweir } 77cdf0e10cSrcweir } 78cdf0e10cSrcweir 79cdf0e10cSrcweir uno::Type SAL_CALL 80cdf0e10cSrcweir ScVbaFormatConditions::getElementType() throw (css::uno::RuntimeException) 81cdf0e10cSrcweir { 82cdf0e10cSrcweir return excel::XFormatCondition::static_type(0); 83cdf0e10cSrcweir } 84cdf0e10cSrcweir 85cdf0e10cSrcweir 86cdf0e10cSrcweir 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 ) 87cdf0e10cSrcweir { 88cdf0e10cSrcweir uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry; 89cdf0e10cSrcweir aObject >>= xSheetConditionalEntry; 90cdf0e10cSrcweir 91cdf0e10cSrcweir uno::Reference< excel::XStyle > xStyle( xStyles->Item( uno::makeAny( xSheetConditionalEntry->getStyleName() ), uno::Any() ), uno::UNO_QUERY_THROW ); 92cdf0e10cSrcweir uno::Reference< excel::XFormatCondition > xCondition = new ScVbaFormatCondition( xRangeParent, xContext, xSheetConditionalEntry, xStyle, xFormatConditions, xRangeProps ); 93cdf0e10cSrcweir return uno::makeAny( xCondition ); 94cdf0e10cSrcweir } 95cdf0e10cSrcweir 96cdf0e10cSrcweir uno::Any 97cdf0e10cSrcweir ScVbaFormatConditions::createCollectionObject(const uno::Any& aObject ) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir return xSheetConditionToFormatCondition( uno::Reference< XHelperInterface >( mxRangeParent, uno::UNO_QUERY_THROW ), mxContext, mxStyles, this, mxParentRangePropertySet, aObject ); 100cdf0e10cSrcweir } 101cdf0e10cSrcweir 102cdf0e10cSrcweir class EnumWrapper : public EnumerationHelper_BASE 103cdf0e10cSrcweir { 104cdf0e10cSrcweir uno::Reference<container::XIndexAccess > m_xIndexAccess; 105cdf0e10cSrcweir uno::Reference<excel::XRange > m_xParentRange; 106cdf0e10cSrcweir uno::Reference<uno::XComponentContext > m_xContext; 107cdf0e10cSrcweir uno::Reference<excel::XStyles > m_xStyles; 108cdf0e10cSrcweir uno::Reference<excel::XFormatConditions > m_xParentCollection; 109cdf0e10cSrcweir uno::Reference<beans::XPropertySet > m_xProps; 110cdf0e10cSrcweir 111cdf0e10cSrcweir sal_Int32 nIndex; 112cdf0e10cSrcweir public: 113cdf0e10cSrcweir 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 ) {} 114cdf0e10cSrcweir virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException) 115cdf0e10cSrcweir { 116cdf0e10cSrcweir return ( nIndex < m_xIndexAccess->getCount() ); 117cdf0e10cSrcweir } 118cdf0e10cSrcweir 119cdf0e10cSrcweir virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir if ( nIndex < m_xIndexAccess->getCount() ) 122cdf0e10cSrcweir return xSheetConditionToFormatCondition( uno::Reference< XHelperInterface >( m_xParentRange, uno::UNO_QUERY_THROW ), m_xContext, m_xStyles, m_xParentCollection, m_xProps, m_xIndexAccess->getByIndex( nIndex++ ) ); 123cdf0e10cSrcweir throw container::NoSuchElementException(); 124cdf0e10cSrcweir } 125cdf0e10cSrcweir }; 126cdf0e10cSrcweir 127cdf0e10cSrcweir uno::Reference< excel::XFormatCondition > SAL_CALL 128cdf0e10cSrcweir ScVbaFormatConditions::Add( ::sal_Int32 _nType, const uno::Any& _aOperator, const uno::Any& _aFormula1, const uno::Any& _aFormula2 ) throw (script::BasicErrorException, uno::RuntimeException) 129cdf0e10cSrcweir { 130cdf0e10cSrcweir return Add( _nType, _aOperator, _aFormula1, _aFormula2, uno::Reference< excel::XStyle >() ); 131cdf0e10cSrcweir } 132cdf0e10cSrcweir 133cdf0e10cSrcweir uno::Reference< excel::XFormatCondition > 134cdf0e10cSrcweir 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) 135cdf0e10cSrcweir { 136cdf0e10cSrcweir // #TODO 137cdf0e10cSrcweir // #FIXME 138cdf0e10cSrcweir // This method will NOT handle r1c1 formulas [*]and only assumes that 139cdf0e10cSrcweir // the formulas are _xlA1 based ( need to hook into calc work ths should 140cdf0e10cSrcweir // address this ) 141cdf0e10cSrcweir // [*] reason: getA1Formula method below is just a hook and just 142cdf0e10cSrcweir // returns whats it gets ( e.g. doesn't convert anything ) 143cdf0e10cSrcweir uno::Reference< excel::XStyle > xStyle( _xStyle ); 144cdf0e10cSrcweir uno::Reference< excel::XFormatCondition > xFormatCondition; 145cdf0e10cSrcweir try 146cdf0e10cSrcweir { 147cdf0e10cSrcweir rtl::OUString sStyleName; 148cdf0e10cSrcweir if ( !xStyle.is() ) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir sStyleName = getStyleName(); 151cdf0e10cSrcweir xStyle = mxStyles->Add(sStyleName, uno::Any() ); 152cdf0e10cSrcweir } 153cdf0e10cSrcweir else 154cdf0e10cSrcweir { 155cdf0e10cSrcweir sStyleName = xStyle->getName(); 156cdf0e10cSrcweir } 157cdf0e10cSrcweir 158cdf0e10cSrcweir VecPropValues aPropertyValueVector; 159cdf0e10cSrcweir sheet::ConditionOperator aType = ScVbaFormatCondition::retrieveAPIType(_nType, uno::Reference< sheet::XSheetCondition >() ); 160cdf0e10cSrcweir uno::Any aValue; 161cdf0e10cSrcweir 162cdf0e10cSrcweir if ( aType == sheet::ConditionOperator_FORMULA) 163cdf0e10cSrcweir aValue = uno::makeAny( sheet::ConditionOperator_FORMULA ); 164cdf0e10cSrcweir else 165cdf0e10cSrcweir aValue = uno::makeAny( ScVbaFormatCondition::retrieveAPIOperator(_aOperator) ); 166cdf0e10cSrcweir 167cdf0e10cSrcweir beans::PropertyValue aProperty( OPERATOR, 0, aValue, beans::PropertyState_DIRECT_VALUE ); 168cdf0e10cSrcweir aPropertyValueVector.push_back( aProperty ); 169cdf0e10cSrcweir 170cdf0e10cSrcweir if ( _aFormula1.hasValue() ) 171cdf0e10cSrcweir { 172cdf0e10cSrcweir beans::PropertyValue aProp( FORMULA1, 0, uno::makeAny( getA1Formula( _aFormula1 ) ), beans::PropertyState_DIRECT_VALUE ); 173cdf0e10cSrcweir aPropertyValueVector.push_back( aProp ); 174cdf0e10cSrcweir } 175cdf0e10cSrcweir if ( _aFormula2.hasValue() ) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir beans::PropertyValue aProp( FORMULA2, 0, uno::makeAny( getA1Formula( _aFormula2 ) ), beans::PropertyState_DIRECT_VALUE ); 178cdf0e10cSrcweir aPropertyValueVector.push_back( aProp ); 179cdf0e10cSrcweir } 180cdf0e10cSrcweir aProperty.Name = STYLENAME; 181cdf0e10cSrcweir aProperty.Value = uno::makeAny( sStyleName ); 182cdf0e10cSrcweir 183cdf0e10cSrcweir // convert vector to sequence 184cdf0e10cSrcweir uno::Sequence< beans::PropertyValue > aPropertyValueList(aPropertyValueVector.size()); 185cdf0e10cSrcweir VecPropValues::iterator it = aPropertyValueVector.begin(); 186cdf0e10cSrcweir VecPropValues::iterator it_end = aPropertyValueVector.end(); 187cdf0e10cSrcweir for ( sal_Int32 index=0; it != it_end; ++it ) 188cdf0e10cSrcweir aPropertyValueList[ index++ ] = *it; 189cdf0e10cSrcweir 190cdf0e10cSrcweir mxSheetConditionalEntries->addNew(aPropertyValueList); 191cdf0e10cSrcweir for (sal_Int32 i = mxSheetConditionalEntries->getCount()-1; i >= 0; i--) 192cdf0e10cSrcweir { 193cdf0e10cSrcweir uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry( mxSheetConditionalEntries->getByIndex(i), uno::UNO_QUERY_THROW ); 194cdf0e10cSrcweir if (xSheetConditionalEntry->getStyleName().equals(sStyleName)) 195cdf0e10cSrcweir { 196cdf0e10cSrcweir xFormatCondition = new ScVbaFormatCondition(uno::Reference< XHelperInterface >( mxRangeParent, uno::UNO_QUERY_THROW ), mxContext, xSheetConditionalEntry, xStyle, this, mxParentRangePropertySet); 197cdf0e10cSrcweir notifyRange(); 198cdf0e10cSrcweir return xFormatCondition; 199cdf0e10cSrcweir } 200cdf0e10cSrcweir } 201cdf0e10cSrcweir } 202cdf0e10cSrcweir catch (uno::Exception& ) 203cdf0e10cSrcweir { 204cdf0e10cSrcweir } 205cdf0e10cSrcweir DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() ); 206cdf0e10cSrcweir return xFormatCondition; 207cdf0e10cSrcweir } 208cdf0e10cSrcweir 209cdf0e10cSrcweir 210cdf0e10cSrcweir uno::Reference< container::XEnumeration > SAL_CALL 211cdf0e10cSrcweir ScVbaFormatConditions::createEnumeration() throw (uno::RuntimeException) 212cdf0e10cSrcweir { 213cdf0e10cSrcweir return new EnumWrapper( m_xIndexAccess, mxRangeParent, mxContext, mxStyles, this, mxParentRangePropertySet ); 214cdf0e10cSrcweir } 215cdf0e10cSrcweir 216cdf0e10cSrcweir 217cdf0e10cSrcweir void 218cdf0e10cSrcweir ScVbaFormatConditions::notifyRange() throw ( script::BasicErrorException ) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir try 221cdf0e10cSrcweir { 222cdf0e10cSrcweir mxParentRangePropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ConditionalFormat")), uno::makeAny( mxSheetConditionalEntries )); 223cdf0e10cSrcweir } 224cdf0e10cSrcweir catch (uno::Exception& ) 225cdf0e10cSrcweir { 226cdf0e10cSrcweir DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString()); 227cdf0e10cSrcweir } 228cdf0e10cSrcweir } 229cdf0e10cSrcweir 230cdf0e10cSrcweir rtl::OUString 231cdf0e10cSrcweir ScVbaFormatConditions::getA1Formula(const css::uno::Any& _aFormula) throw ( script::BasicErrorException ) 232cdf0e10cSrcweir { 233cdf0e10cSrcweir // #TODO, #FIXME hook-in proper formula conversion detection & logic 234cdf0e10cSrcweir rtl::OUString sFormula; 235cdf0e10cSrcweir if ( !( _aFormula >>= sFormula ) ) 236cdf0e10cSrcweir DebugHelper::exception(SbERR_BAD_PARAMETER, rtl::OUString() ); 237cdf0e10cSrcweir return sFormula; 238cdf0e10cSrcweir } 239cdf0e10cSrcweir 240cdf0e10cSrcweir rtl::OUString 241cdf0e10cSrcweir ScVbaFormatConditions::getStyleName() 242cdf0e10cSrcweir { 243cdf0e10cSrcweir ScVbaStyles* pStyles = static_cast< ScVbaStyles* >( mxStyles.get() ); 244cdf0e10cSrcweir if ( !pStyles ) 245cdf0e10cSrcweir DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() ); 246cdf0e10cSrcweir uno::Sequence< rtl::OUString > sCellStyleNames = pStyles->getStyleNames(); 247cdf0e10cSrcweir return ContainerUtilities::getUniqueName(sCellStyleNames, sStyleNamePrefix, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_") )); 248cdf0e10cSrcweir } 249cdf0e10cSrcweir 250cdf0e10cSrcweir void 251cdf0e10cSrcweir ScVbaFormatConditions::removeFormatCondition( const rtl::OUString& _sStyleName, sal_Bool _bRemoveStyle) throw ( script::BasicErrorException ) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir try 254cdf0e10cSrcweir { 255cdf0e10cSrcweir sal_Int32 nElems = mxSheetConditionalEntries->getCount(); 256cdf0e10cSrcweir for (sal_Int32 i = 0; i < nElems; i++) 257cdf0e10cSrcweir { 258cdf0e10cSrcweir uno::Reference< sheet::XSheetConditionalEntry > xSheetConditionalEntry( mxSheetConditionalEntries->getByIndex(i), uno::UNO_QUERY_THROW ); 259cdf0e10cSrcweir if (_sStyleName.equals(xSheetConditionalEntry->getStyleName())) 260cdf0e10cSrcweir { 261cdf0e10cSrcweir mxSheetConditionalEntries->removeByIndex(i); 262cdf0e10cSrcweir if (_bRemoveStyle) 263cdf0e10cSrcweir { 264cdf0e10cSrcweir ScVbaStyles* pStyles = static_cast< ScVbaStyles* >( mxStyles.get() ); 265cdf0e10cSrcweir if ( !pStyles ) 266cdf0e10cSrcweir DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString()); 267cdf0e10cSrcweir pStyles->Delete( _sStyleName ); 268cdf0e10cSrcweir } 269cdf0e10cSrcweir return; 270cdf0e10cSrcweir } 271cdf0e10cSrcweir } 272cdf0e10cSrcweir } 273cdf0e10cSrcweir catch (uno::Exception& ) 274cdf0e10cSrcweir { 275cdf0e10cSrcweir DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString()); 276cdf0e10cSrcweir } 277cdf0e10cSrcweir } 278cdf0e10cSrcweir 279cdf0e10cSrcweir rtl::OUString& 280cdf0e10cSrcweir ScVbaFormatConditions::getServiceImplName() 281cdf0e10cSrcweir { 282cdf0e10cSrcweir static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaFormatConditions") ); 283cdf0e10cSrcweir return sImplName; 284cdf0e10cSrcweir } 285cdf0e10cSrcweir 286cdf0e10cSrcweir uno::Sequence< rtl::OUString > 287cdf0e10cSrcweir ScVbaFormatConditions::getServiceNames() 288cdf0e10cSrcweir { 289cdf0e10cSrcweir static uno::Sequence< rtl::OUString > aServiceNames; 290cdf0e10cSrcweir if ( aServiceNames.getLength() == 0 ) 291cdf0e10cSrcweir { 292cdf0e10cSrcweir aServiceNames.realloc( 1 ); 293cdf0e10cSrcweir aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.FormatConditions" ) ); 294cdf0e10cSrcweir } 295cdf0e10cSrcweir return aServiceNames; 296cdf0e10cSrcweir } 297cdf0e10cSrcweir 298