diff options
Diffstat (limited to 'sc/source/ui/vba/vbavalidation.cxx')
-rw-r--r-- | sc/source/ui/vba/vbavalidation.cxx | 382 |
1 files changed, 382 insertions, 0 deletions
diff --git a/sc/source/ui/vba/vbavalidation.cxx b/sc/source/ui/vba/vbavalidation.cxx new file mode 100644 index 0000000000..a30b43fe73 --- /dev/null +++ b/sc/source/ui/vba/vbavalidation.cxx @@ -0,0 +1,382 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "vbavalidation.hxx" +#include "vbaformatcondition.hxx" +#include <com/sun/star/sheet/XSheetCondition.hpp> +#include <com/sun/star/sheet/ValidationType.hpp> +#include <com/sun/star/sheet/ValidationAlertStyle.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <ooo/vba/excel/XlDVType.hpp> +#include <ooo/vba/excel/XlDVAlertStyle.hpp> + +#include <unonames.hxx> +#include <rangelst.hxx> +#include "excelvbahelper.hxx" +#include "vbarange.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; + +static void +lcl_setValidationProps( const uno::Reference< table::XCellRange >& xRange, const uno::Reference< beans::XPropertySet >& xProps ) +{ + uno::Reference< beans::XPropertySet > xRangeProps( xRange, uno::UNO_QUERY_THROW ); + xRangeProps->setPropertyValue( SC_UNONAME_VALIDAT , uno::Any( xProps ) ); +} + +static uno::Reference< beans::XPropertySet > +lcl_getValidationProps( const uno::Reference< table::XCellRange >& xRange ) +{ + uno::Reference< beans::XPropertySet > xProps( xRange, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xValProps; + xValProps.set( xProps->getPropertyValue( SC_UNONAME_VALIDAT ), uno::UNO_QUERY_THROW ); + return xValProps; +} + +sal_Bool SAL_CALL +ScVbaValidation::getIgnoreBlank() +{ + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) ); + bool bBlank = false; + xProps->getPropertyValue( SC_UNONAME_IGNOREBL ) >>= bBlank; + return bBlank; +} + +void SAL_CALL +ScVbaValidation::setIgnoreBlank( sal_Bool _ignoreblank ) +{ + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) ); + xProps->setPropertyValue( SC_UNONAME_IGNOREBL, uno::Any( _ignoreblank ) ); + lcl_setValidationProps( m_xRange, xProps ); +} + +sal_Bool SAL_CALL +ScVbaValidation::getInCellDropdown() +{ + uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange ); + sal_Int32 nShowList = 0; + xProps->getPropertyValue( SC_UNONAME_SHOWLIST ) >>= nShowList; + return nShowList != 0; +} + +void SAL_CALL +ScVbaValidation::setInCellDropdown( sal_Bool _incelldropdown ) +{ + sal_Int32 nDropDown = 0; + if ( _incelldropdown ) + nDropDown = 1; + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps(m_xRange) ); + xProps->setPropertyValue( SC_UNONAME_SHOWLIST, uno::Any( nDropDown ) ); + lcl_setValidationProps( m_xRange, xProps ); +} + +sal_Bool SAL_CALL +ScVbaValidation::getShowInput() +{ + uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange ); + bool bShowInput = false; + xProps->getPropertyValue( SC_UNONAME_SHOWINP ) >>= bShowInput; + return bShowInput; +} + +void SAL_CALL +ScVbaValidation:: setShowInput( sal_Bool _showinput ) +{ + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps(m_xRange) ); + xProps->setPropertyValue( SC_UNONAME_IGNOREBL, uno::Any( _showinput ) ); + lcl_setValidationProps( m_xRange, xProps ); +} + +sal_Bool SAL_CALL +ScVbaValidation::getShowError() +{ + uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange ); + bool bShowError = false; + xProps->getPropertyValue( SC_UNONAME_SHOWERR ) >>= bShowError; + return bShowError; +} + +void SAL_CALL +ScVbaValidation::setShowError( sal_Bool _showerror ) +{ + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) ); + xProps->setPropertyValue( SC_UNONAME_SHOWERR, uno::Any( _showerror ) ); + lcl_setValidationProps( m_xRange, xProps ); +} + +OUString SAL_CALL +ScVbaValidation::getErrorTitle() +{ + uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange ); + OUString sErrorTitle; + xProps->getPropertyValue( SC_UNONAME_ERRTITLE ) >>= sErrorTitle; + return sErrorTitle; +} + +void +ScVbaValidation::setErrorTitle( const OUString& _errormessage ) +{ + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) ); + xProps->setPropertyValue( SC_UNONAME_ERRTITLE, uno::Any( _errormessage ) ); + lcl_setValidationProps( m_xRange, xProps ); +} + +OUString SAL_CALL +ScVbaValidation::getInputMessage() +{ + uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange ); + OUString sMsg; + xProps->getPropertyValue( SC_UNONAME_INPMESS ) >>= sMsg; + return sMsg; +} + +void SAL_CALL +ScVbaValidation::setInputMessage( const OUString& _inputmessage ) +{ + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) ); + xProps->setPropertyValue( SC_UNONAME_INPMESS, uno::Any( _inputmessage ) ); + lcl_setValidationProps( m_xRange, xProps ); +} + +OUString SAL_CALL +ScVbaValidation::getInputTitle() +{ + uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange ); + OUString sString; + xProps->getPropertyValue( SC_UNONAME_INPTITLE ) >>= sString; + return sString; +} + +void SAL_CALL +ScVbaValidation::setInputTitle( const OUString& _inputtitle ) +{ + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) ); + xProps->setPropertyValue( SC_UNONAME_INPTITLE, uno::Any( _inputtitle ) ); + lcl_setValidationProps( m_xRange, xProps ); +} + +OUString SAL_CALL +ScVbaValidation::getErrorMessage() +{ + uno::Reference< beans::XPropertySet > xProps = lcl_getValidationProps( m_xRange ); + OUString sString; + xProps->getPropertyValue( SC_UNONAME_ERRMESS ) >>= sString; + return sString; +} + +void SAL_CALL +ScVbaValidation::setErrorMessage( const OUString& _errormessage ) +{ + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) ); + xProps->setPropertyValue( SC_UNONAME_ERRMESS, uno::Any( _errormessage ) ); + lcl_setValidationProps( m_xRange, xProps ); +} + +void SAL_CALL +ScVbaValidation::Delete( ) +{ + OUString sBlank; + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) ); + uno::Reference< sheet::XSheetCondition > xCond( xProps, uno::UNO_QUERY_THROW ); + xProps->setPropertyValue( SC_UNONAME_IGNOREBL, uno::Any( true ) ); + xProps->setPropertyValue( SC_UNONAME_SHOWINP, uno::Any( true ) ); + xProps->setPropertyValue( SC_UNONAME_SHOWERR, uno::Any( true ) ); + xProps->setPropertyValue( SC_UNONAME_ERRTITLE, uno::Any( sBlank ) ); + xProps->setPropertyValue( SC_UNONAME_INPMESS, uno::Any( sBlank) ); + xProps->setPropertyValue( SC_UNONAME_ERRALSTY, uno::Any( sheet::ValidationAlertStyle_STOP) ); + xProps->setPropertyValue( SC_UNONAME_TYPE, uno::Any( sheet::ValidationType_ANY ) ); + xCond->setFormula1( sBlank ); + xCond->setFormula2( sBlank ); + xCond->setOperator( sheet::ConditionOperator_NONE ); + + lcl_setValidationProps( m_xRange, xProps ); +} + +// Fix the defect that validation cannot work when the input should be limited between a lower bound and an upper bound +void SAL_CALL +ScVbaValidation::Add( const uno::Any& Type, const uno::Any& AlertStyle, const uno::Any& Operator, const uno::Any& Formula1, const uno::Any& Formula2 ) +{ + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) ); + uno::Reference< sheet::XSheetCondition > xCond( xProps, uno::UNO_QUERY_THROW ); + + sheet::ValidationType nValType = sheet::ValidationType_ANY; + xProps->getPropertyValue( SC_UNONAME_TYPE ) >>= nValType; + if ( nValType != sheet::ValidationType_ANY ) + throw uno::RuntimeException("validation object already exists" ); + sal_Int32 nType = -1; + if ( !Type.hasValue() || !( Type >>= nType ) ) + throw uno::RuntimeException("missing required param" ); + + Delete(); // set up defaults + OUString sFormula1; + Formula1 >>= sFormula1; + OUString sFormula2; + Formula2 >>= sFormula2; + switch ( nType ) + { + case excel::XlDVType::xlValidateList: + { + // for validate list + // at least formula1 is required + if ( !Formula1.hasValue() ) + throw uno::RuntimeException("missing param" ); + nValType = sheet::ValidationType_LIST; + xProps->setPropertyValue( SC_UNONAME_TYPE, uno::Any(nValType )); + // #TODO validate required params + // #TODO need to correct the ';' delimited formula on get/set + break; + } + case excel::XlDVType::xlValidateWholeNumber: + nValType = sheet::ValidationType_WHOLE; + xProps->setPropertyValue( SC_UNONAME_TYPE, uno::Any(nValType )); + break; + default: + throw uno::RuntimeException("unsupported operation..." ); + } + + sheet::ValidationAlertStyle eStyle = sheet::ValidationAlertStyle_STOP; + sal_Int32 nVbaAlertStyle = excel::XlDVAlertStyle::xlValidAlertStop; + if ( AlertStyle.hasValue() && ( AlertStyle >>= nVbaAlertStyle ) ) + { + switch( nVbaAlertStyle ) + { + case excel::XlDVAlertStyle::xlValidAlertStop: + // yes I know it's already defaulted but safer to assume + // someone probably could change the code above + eStyle = sheet::ValidationAlertStyle_STOP; + break; + case excel::XlDVAlertStyle::xlValidAlertWarning: + eStyle = sheet::ValidationAlertStyle_WARNING; + break; + case excel::XlDVAlertStyle::xlValidAlertInformation: + eStyle = sheet::ValidationAlertStyle_INFO; + break; + default: + throw uno::RuntimeException("bad param..." ); + + } + } + + xProps->setPropertyValue( SC_UNONAME_ERRALSTY, uno::Any( eStyle ) ); + + // i#108860: fix the defect that validation cannot work when the input + // should be limited between a lower bound and an upper bound + if ( Operator.hasValue() ) + { + css::sheet::ConditionOperator conOperator = ScVbaFormatCondition::retrieveAPIOperator( Operator ); + xCond->setOperator( conOperator ); + } + + if ( !sFormula1.isEmpty() ) + xCond->setFormula1( sFormula1 ); + if ( !sFormula2.isEmpty() ) + xCond->setFormula2( sFormula2 ); + + lcl_setValidationProps( m_xRange, xProps ); +} + +OUString SAL_CALL +ScVbaValidation::getFormula1() +{ + uno::Reference< sheet::XSheetCondition > xCond( lcl_getValidationProps( m_xRange ), uno::UNO_QUERY_THROW ); + OUString sString = xCond->getFormula1(); + + ScRefFlags nFlags = ScRefFlags::ZERO; + ScRangeList aCellRanges; + + ScDocShell* pDocSh = excel::GetDocShellFromRange( m_xRange ); + // in calc validation formula is either a range or formula + // that results in range. + // In VBA both formula and address can have a leading '=' + // in result of getFormula1, however it *seems* that a named range or + // real formula has to (or is expected to) have the '=' + if ( pDocSh && !ScVbaRange::getCellRangesForAddress( nFlags, sString, pDocSh, aCellRanges, formula::FormulaGrammar::CONV_XL_A1, 0 ) ) + sString = "=" + sString; + return sString; +} + +OUString SAL_CALL +ScVbaValidation::getFormula2() +{ + uno::Reference< sheet::XSheetCondition > xCond( lcl_getValidationProps( m_xRange ), uno::UNO_QUERY_THROW ); + return xCond->getFormula2(); +} + +sal_Int32 SAL_CALL +ScVbaValidation::getType() +{ + uno::Reference< beans::XPropertySet > xProps( lcl_getValidationProps( m_xRange ) ); + sheet::ValidationType nValType = sheet::ValidationType_ANY; + xProps->getPropertyValue( SC_UNONAME_TYPE ) >>= nValType; + sal_Int32 nExcelType = excel::XlDVType::xlValidateList; // pick a default + if ( xProps.is() ) + { + switch ( nValType ) + { + case sheet::ValidationType_LIST: + nExcelType = excel::XlDVType::xlValidateList; + break; + case sheet::ValidationType_ANY: // not ANY not really a great match for anything I fear:-( + nExcelType = excel::XlDVType::xlValidateInputOnly; + break; + case sheet::ValidationType_CUSTOM: + nExcelType = excel::XlDVType::xlValidateCustom; + break; + case sheet::ValidationType_WHOLE: + nExcelType = excel::XlDVType::xlValidateWholeNumber; + break; + case sheet::ValidationType_DECIMAL: + nExcelType = excel::XlDVType::xlValidateDecimal; + break; + case sheet::ValidationType_DATE: + nExcelType = excel::XlDVType::xlValidateDate; + break; + case sheet::ValidationType_TIME: + nExcelType = excel::XlDVType::xlValidateTime; + break; + case sheet::ValidationType_TEXT_LEN: + nExcelType = excel::XlDVType::xlValidateTextLength; + break; + case sheet::ValidationType::ValidationType_MAKE_FIXED_SIZE: + default: + break; + } + } + return nExcelType; +} + +OUString +ScVbaValidation::getServiceImplName() +{ + return "ScVbaValidation"; +} + +uno::Sequence< OUString > +ScVbaValidation::getServiceNames() +{ + static uno::Sequence< OUString > const aServiceNames + { + "ooo.vba.excel.Validation" + }; + return aServiceNames; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |