sc/inc/cellsuno.hxx | 8 +++- sc/inc/fmtuno.hxx | 2 - sc/source/filter/oox/worksheethelper.cxx | 58 ++++++++++++------------------- sc/source/ui/unoobj/cellsuno.cxx | 58 +++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 37 deletions(-)
New commits: commit 79322a7025bb6fd61928204f90230560b09b4ba9 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Wed May 21 15:28:41 2025 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Fri May 23 09:46:24 2025 +0200 tdf#166684 strip out some unnecessary UNO work to make this easier to optimise, strip out some unnecessary UNO stuff between the import filter and the underlying spreadsheet model Change-Id: I5d0ea6ffc487f089c87f17fd2eb18a30198dbacc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185647 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sc/inc/cellsuno.hxx b/sc/inc/cellsuno.hxx index 6b109aa55000..959757168d28 100644 --- a/sc/inc/cellsuno.hxx +++ b/sc/inc/cellsuno.hxx @@ -113,6 +113,7 @@ class SfxItemPropertyMap; class SfxItemPropertySet; struct SfxItemPropertyMapEntry; class ScTableRowsObj; +class ScTableValidationObj; class SolarMutexGuard; namespace editeng { class SvxBorderLine; } @@ -253,6 +254,9 @@ public: void SetCursorOnly(bool bSet); bool IsCursorOnly() const { return bCursorOnly; } + SC_DLLPUBLIC rtl::Reference<ScTableValidationObj> getValidation(); + SC_DLLPUBLIC void setValidation(const rtl::Reference<ScTableValidationObj>&); + // XSheetOperation virtual double SAL_CALL computeFunction( css::sheet::GeneralFunction nFunction ) override; virtual void SAL_CALL clearContents( sal_Int32 nContentFlags ) override; @@ -379,7 +383,7 @@ using ScCellRangesObj_BASE = cppu::ImplInheritanceHelper<ScCellRangesBase, css::sheet::XSheetCellRangeContainer, css::container::XNameContainer, css::container::XEnumerationAccess>; -class UNLESS_MERGELIBS(SC_DLLPUBLIC) ScCellRangesObj final : public ScCellRangesObj_BASE +class SC_DLLPUBLIC ScCellRangesObj final : public ScCellRangesObj_BASE { public: struct ScNamedEntry @@ -448,6 +452,8 @@ public: virtual OUString SAL_CALL getImplementationName() override; virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + void addRangeAddresses( const ScRangeList& rRanges, bool bMergeRanges ); }; using ScCellRangeObj_BASE = cppu::ImplInheritanceHelper<ScCellRangesBase, diff --git a/sc/inc/fmtuno.hxx b/sc/inc/fmtuno.hxx index 5e7cefbd3f17..ac680ae05bc5 100644 --- a/sc/inc/fmtuno.hxx +++ b/sc/inc/fmtuno.hxx @@ -147,7 +147,7 @@ public: virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; }; -class ScTableValidationObj final : public cppu::WeakImplHelper< +class SC_DLLPUBLIC ScTableValidationObj final : public cppu::WeakImplHelper< css::sheet::XSheetCondition2, css::sheet::XMultiFormulaTokens, css::beans::XPropertySet, diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx index 6e846904c1a7..ae1db7f75463 100644 --- a/sc/source/filter/oox/worksheethelper.cxx +++ b/sc/source/filter/oox/worksheethelper.cxx @@ -71,6 +71,8 @@ #include <cellvalue.hxx> #include <columnspanset.hxx> #include <dbdata.hxx> +#include <cellsuno.hxx> +#include <fmtuno.hxx> #include <svl/stritem.hxx> #include <editeng/eeitem.hxx> @@ -229,7 +231,7 @@ public: /** Returns the XCellRange interface for the passed cell range address. */ Reference< XCellRange > getCellRange( const ScRange& rRange ) const; /** Returns the XSheetCellRanges interface for the passed cell range addresses. */ - Reference< XSheetCellRanges > getCellRangeList( const ScRangeList& rRanges ) const; + rtl::Reference<ScCellRangesObj> getCellRangeList( const ScRangeList& rRanges ) const; /** Returns the XCellRange interface for a column. */ Reference< XCellRange > getColumn( sal_Int32 nCol ) const; @@ -402,8 +404,6 @@ private: bool mbHasDefWidth; /// True = default column width is set from defaultColWidth attribute. }; -constexpr OUStringLiteral gaSheetCellRanges( u"com.sun.star.sheet.SheetCellRanges" ); /// Service name for a SheetCellRanges object. - WorksheetGlobals::WorksheetGlobals( const WorkbookHelper& rHelper, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, SCTAB nSheet ) : WorkbookHelper( rHelper ), mrMaxApiPos( rHelper.getAddressConverter().getMaxApiAddress() ), @@ -479,17 +479,14 @@ Reference< XCellRange > WorksheetGlobals::getCellRange( const ScRange& rRange ) return xRange; } -Reference< XSheetCellRanges > WorksheetGlobals::getCellRangeList( const ScRangeList& rRanges ) const +rtl::Reference<ScCellRangesObj> WorksheetGlobals::getCellRangeList( const ScRangeList& rRanges ) const { - Reference< XSheetCellRanges > xRanges; - if( mxSheet.is() && !rRanges.empty() ) try - { - xRanges.set( getBaseFilter().getModelFactory()->createInstance( gaSheetCellRanges ), UNO_QUERY_THROW ); - Reference< XSheetCellRangeContainer > xRangeCont( xRanges, UNO_QUERY_THROW ); - xRangeCont->addRangeAddresses( AddressConverter::toApiSequence(rRanges), false ); - } - catch( Exception& ) + rtl::Reference<ScCellRangesObj> xRanges; + if( mxSheet.is() && !rRanges.empty() ) { + ScDocShell* pDocShell = getScDocument().GetDocumentShell(); + xRanges = new ScCellRangesObj(pDocShell, ScRangeList()); + xRanges->addRangeAddresses( rRanges, false ); } return xRanges; } @@ -1090,12 +1087,12 @@ void WorksheetGlobals::finalizeValidationRanges() const { for (auto const& validation : maValidations) { - PropertySet aPropSet( getCellRangeList(validation.maRanges) ); + rtl::Reference<ScCellRangesObj> xRanges = getCellRangeList(validation.maRanges); + rtl::Reference<ScTableValidationObj> xValidation = xRanges->getValidation(); - Reference< XPropertySet > xValidation( aPropSet.getAnyProperty( PROP_Validation ), UNO_QUERY ); if( xValidation.is() ) { - PropertySet aValProps( xValidation ); + PropertySet aValProps(( Reference< XPropertySet >(xValidation) )); try { @@ -1109,8 +1106,7 @@ void WorksheetGlobals::finalizeValidationRanges() const xCell = xDBCellRange->getCellByPosition( 0, 0 ); Reference<XCellAddressable> xCellAddressable( xCell, UNO_QUERY_THROW ); CellAddress aFirstCell = xCellAddressable->getCellAddress(); - Reference<XSheetCondition> xCondition( xValidation, UNO_QUERY_THROW ); - xCondition->setSourcePosition( aFirstCell ); + xValidation->setSourcePosition( aFirstCell ); } catch(const Exception&) { @@ -1158,26 +1154,18 @@ void WorksheetGlobals::finalizeValidationRanges() const // allow blank cells aValProps.setProperty( PROP_IgnoreBlankCells, validation.mbAllowBlank ); - try - { - // condition operator - Reference< XSheetCondition2 > xSheetCond( xValidation, UNO_QUERY_THROW ); - if( eType == ValidationType_CUSTOM ) - xSheetCond->setConditionOperator( ConditionOperator2::FORMULA ); - else - xSheetCond->setConditionOperator( CondFormatBuffer::convertToApiOperator( validation.mnOperator ) ); - - // condition formulas - Reference< XMultiFormulaTokens > xTokens( xValidation, UNO_QUERY_THROW ); - xTokens->setTokens( 0, validation.maTokens1 ); - xTokens->setTokens( 1, validation.maTokens2 ); - } - catch( Exception& ) - { - } + // condition operator + if( eType == ValidationType_CUSTOM ) + xValidation->setConditionOperator( ConditionOperator2::FORMULA ); + else + xValidation->setConditionOperator( CondFormatBuffer::convertToApiOperator( validation.mnOperator ) ); + + // condition formulas + xValidation->setTokens( 0, validation.maTokens1 ); + xValidation->setTokens( 1, validation.maTokens2 ); // write back validation settings to cell range(s) - aPropSet.setProperty( PROP_Validation, xValidation ); + xRanges->setValidation( xValidation ); } } } diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index 8ec282502609..0c57107fea2c 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -2455,6 +2455,57 @@ void ScCellRangesBase::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntr } } +rtl::Reference<ScTableValidationObj> ScCellRangesBase::getValidation() +{ + SolarMutexGuard aGuard; + + const ScPatternAttr* pPattern = GetCurrentAttrsDeep(); + if ( !pPattern ) + return nullptr; + + if ( !pDocShell || aRanges.empty() ) + throw uno::RuntimeException(); + + const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class + const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( u"Validation" ); + assert(pEntry); + + ScDocument& rDoc = pDocShell->GetDocument(); + bool bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC ); + bool bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML ); + formula::FormulaGrammar::Grammar eGrammar = (bXML ? + rDoc.GetStorageGrammar() : + formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML)); + sal_uLong nIndex = + pPattern->GetItem(ATTR_VALIDDATA).GetValue(); + return new ScTableValidationObj( rDoc, nIndex, eGrammar ); +} + +void ScCellRangesBase::setValidation(const rtl::Reference<ScTableValidationObj>& pValidObj) +{ + SolarMutexGuard aGuard; + + const SfxItemPropertyMap& rPropertyMap = GetItemPropertyMap(); // from derived class + const SfxItemPropertyMapEntry* pEntry = rPropertyMap.getByName( u"Validation" ); + assert(pEntry); + + ScDocument& rDoc = pDocShell->GetDocument(); + bool bEnglish = ( pEntry->nWID != SC_WID_UNO_VALILOC ); + bool bXML = ( pEntry->nWID == SC_WID_UNO_VALIXML ); + formula::FormulaGrammar::Grammar eGrammar = (bXML ? + formula::FormulaGrammar::GRAM_UNSPECIFIED : + formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML)); + + std::unique_ptr<ScValidationData> pNewData( + pValidObj->CreateValidationData( rDoc, eGrammar )); + sal_uInt32 nIndex = rDoc.AddValidationEntry( *pNewData ); + pNewData.reset(); + + ScPatternAttr aPattern(rDoc.getCellAttributeHelper()); + aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nIndex ) ); + pDocShell->GetDocFunc().ApplyAttributes( *GetMarkData(), aPattern, true ); +} + void SAL_CALL ScCellRangesBase::addPropertyChangeListener( const OUString& /* aPropertyName */, const uno::Reference<beans::XPropertyChangeListener>& /* aListener */) { @@ -4082,6 +4133,13 @@ void SAL_CALL ScCellRangesObj::addRangeAddresses( const uno::Sequence<table::Cel } } +void ScCellRangesObj::addRangeAddresses( const ScRangeList& rRanges, bool bMergeRanges ) +{ + SolarMutexGuard aGuard; + for (const ScRange& rRange : rRanges) + AddRange(rRange, bMergeRanges); +} + void SAL_CALL ScCellRangesObj::removeRangeAddresses( const uno::Sequence<table::CellRangeAddress >& rRangeSeq ) { // use sometimes a better/faster implementation