diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2020-08-07 16:34:54 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2020-08-08 10:42:13 +0200 |
commit | 358bdc5eb38a6a7c310027f4a10694230b848b7f (patch) | |
tree | c353588dfcba6cb242dc1383e476521f5247ebb1 /sc | |
parent | 800eebfa82106c509310ed43bef38a7a4ad4451f (diff) |
loplugin:flatten in sc/filter/oox
Change-Id: Idd536dbeaee1f1db3317d96b90e56691976a89ee
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100338
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'sc')
23 files changed, 1153 insertions, 1126 deletions
diff --git a/sc/source/filter/oox/autofilterbuffer.cxx b/sc/source/filter/oox/autofilterbuffer.cxx index 8e77d935d9a2..6cb33c4d2658 100644 --- a/sc/source/filter/oox/autofilterbuffer.cxx +++ b/sc/source/filter/oox/autofilterbuffer.cxx @@ -556,86 +556,86 @@ FilterColumn& AutoFilter::createFilterColumn() void AutoFilter::finalizeImport( const Reference<XSheetFilterDescriptor3>& rxFilterDesc ) { - if( rxFilterDesc.is() ) + if( !rxFilterDesc.is() ) + return; + + // set some common properties for the auto filter range + PropertySet aDescProps( rxFilterDesc ); + aDescProps.setProperty( PROP_IsCaseSensitive, false ); + aDescProps.setProperty( PROP_SkipDuplicates, false ); + aDescProps.setProperty( PROP_Orientation, TableOrientation_ROWS ); + aDescProps.setProperty( PROP_ContainsHeader, true ); + aDescProps.setProperty( PROP_CopyOutputData, false ); + + // maximum number of UNO API filter fields + sal_Int32 nMaxCount = 0; + aDescProps.getProperty( nMaxCount, PROP_MaxFieldCount ); + OSL_ENSURE( nMaxCount > 0, "AutoFilter::finalizeImport - invalid maximum filter field count" ); + + // resulting list of all UNO API filter fields + ::std::vector<TableFilterField3> aFilterFields; + + // track if columns require to enable or disable regular expressions + OptValue< bool > obNeedsRegExp; + + /* Track whether the filter fields of the first filter column are + connected with 'or'. In this case, other filter fields cannot be + inserted without altering the result of the entire filter, due to + Calc's precedence for the 'and' connection operator. Example: + Excel's filter conditions 'A1 and (B1 or B2) and C1' where B1 and + B2 belong to filter column B, will be evaluated by Calc as + '(A1 and B1) or (B2 and C1)'. */ + bool bHasOrConnection = false; + + // process all filter column objects, exit when 'or' connection exists + for( const auto& rxFilterColumn : maFilterColumns ) { - // set some common properties for the auto filter range - PropertySet aDescProps( rxFilterDesc ); - aDescProps.setProperty( PROP_IsCaseSensitive, false ); - aDescProps.setProperty( PROP_SkipDuplicates, false ); - aDescProps.setProperty( PROP_Orientation, TableOrientation_ROWS ); - aDescProps.setProperty( PROP_ContainsHeader, true ); - aDescProps.setProperty( PROP_CopyOutputData, false ); - - // maximum number of UNO API filter fields - sal_Int32 nMaxCount = 0; - aDescProps.getProperty( nMaxCount, PROP_MaxFieldCount ); - OSL_ENSURE( nMaxCount > 0, "AutoFilter::finalizeImport - invalid maximum filter field count" ); - - // resulting list of all UNO API filter fields - ::std::vector<TableFilterField3> aFilterFields; - - // track if columns require to enable or disable regular expressions - OptValue< bool > obNeedsRegExp; - - /* Track whether the filter fields of the first filter column are - connected with 'or'. In this case, other filter fields cannot be - inserted without altering the result of the entire filter, due to - Calc's precedence for the 'and' connection operator. Example: - Excel's filter conditions 'A1 and (B1 or B2) and C1' where B1 and - B2 belong to filter column B, will be evaluated by Calc as - '(A1 and B1) or (B2 and C1)'. */ - bool bHasOrConnection = false; - - // process all filter column objects, exit when 'or' connection exists - for( const auto& rxFilterColumn : maFilterColumns ) + // the filter settings object creates a list of filter fields + ApiFilterSettings aSettings = rxFilterColumn->finalizeImport( nMaxCount ); + ApiFilterSettings::FilterFieldVector& rColumnFields = aSettings.maFilterFields; + + // new total number of filter fields + sal_Int32 nNewCount = static_cast< sal_Int32 >( aFilterFields.size() + rColumnFields.size() ); + + /* Check whether mode for regular expressions is compatible with + the global mode in obNeedsRegExp. If either one is still in + don't-care state, all is fine. If both are set, they must be + equal. */ + bool bRegExpCompatible = !obNeedsRegExp || !aSettings.mobNeedsRegExp || (obNeedsRegExp.get() == aSettings.mobNeedsRegExp.get()); + + // check whether fields are connected by 'or' (see comments above). + if( rColumnFields.size() >= 2 ) + bHasOrConnection = std::any_of(rColumnFields.begin() + 1, rColumnFields.end(), + [](const css::sheet::TableFilterField3& rColumnField) { return rColumnField.Connection == FilterConnection_OR; }); + + /* Skip the column filter, if no filter fields have been created, + if the number of new filter fields would exceed the total limit + of filter fields, or if the mode for regular expressions of the + filter column does not fit. */ + if( !rColumnFields.empty() && (nNewCount <= nMaxCount) && bRegExpCompatible ) { - // the filter settings object creates a list of filter fields - ApiFilterSettings aSettings = rxFilterColumn->finalizeImport( nMaxCount ); - ApiFilterSettings::FilterFieldVector& rColumnFields = aSettings.maFilterFields; - - // new total number of filter fields - sal_Int32 nNewCount = static_cast< sal_Int32 >( aFilterFields.size() + rColumnFields.size() ); - - /* Check whether mode for regular expressions is compatible with - the global mode in obNeedsRegExp. If either one is still in - don't-care state, all is fine. If both are set, they must be - equal. */ - bool bRegExpCompatible = !obNeedsRegExp || !aSettings.mobNeedsRegExp || (obNeedsRegExp.get() == aSettings.mobNeedsRegExp.get()); - - // check whether fields are connected by 'or' (see comments above). - if( rColumnFields.size() >= 2 ) - bHasOrConnection = std::any_of(rColumnFields.begin() + 1, rColumnFields.end(), - [](const css::sheet::TableFilterField3& rColumnField) { return rColumnField.Connection == FilterConnection_OR; }); - - /* Skip the column filter, if no filter fields have been created, - if the number of new filter fields would exceed the total limit - of filter fields, or if the mode for regular expressions of the - filter column does not fit. */ - if( !rColumnFields.empty() && (nNewCount <= nMaxCount) && bRegExpCompatible ) - { - /* Add 'and' connection to the first filter field to connect - it to the existing filter fields of other columns. */ - rColumnFields[ 0 ].Connection = FilterConnection_AND; - - // insert the new filter fields - aFilterFields.insert( aFilterFields.end(), rColumnFields.begin(), rColumnFields.end() ); + /* Add 'and' connection to the first filter field to connect + it to the existing filter fields of other columns. */ + rColumnFields[ 0 ].Connection = FilterConnection_AND; - // update the regular expressions mode - obNeedsRegExp.assignIfUsed( aSettings.mobNeedsRegExp ); - } + // insert the new filter fields + aFilterFields.insert( aFilterFields.end(), rColumnFields.begin(), rColumnFields.end() ); - if( bHasOrConnection ) - break; + // update the regular expressions mode + obNeedsRegExp.assignIfUsed( aSettings.mobNeedsRegExp ); } - // insert all filter fields to the filter descriptor - if( !aFilterFields.empty() ) - rxFilterDesc->setFilterFields3( ContainerHelper::vectorToSequence( aFilterFields ) ); - - // regular expressions - bool bUseRegExp = obNeedsRegExp.get( false ); - aDescProps.setProperty( PROP_UseRegularExpressions, bUseRegExp ); + if( bHasOrConnection ) + break; } + + // insert all filter fields to the filter descriptor + if( !aFilterFields.empty() ) + rxFilterDesc->setFilterFields3( ContainerHelper::vectorToSequence( aFilterFields ) ); + + // regular expressions + bool bUseRegExp = obNeedsRegExp.get( false ); + aDescProps.setProperty( PROP_UseRegularExpressions, bUseRegExp ); } AutoFilterBuffer::AutoFilterBuffer( const WorkbookHelper& rHelper ) : @@ -653,59 +653,61 @@ AutoFilter& AutoFilterBuffer::createAutoFilter() void AutoFilterBuffer::finalizeImport( sal_Int16 nSheet ) { // rely on existence of the defined name '_FilterDatabase' containing the range address of the filtered area - if( const DefinedName* pFilterDBName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_FILTERDATABASE, nSheet ).get() ) + const DefinedName* pFilterDBName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_FILTERDATABASE, nSheet ).get(); + if(!pFilterDBName) + return; + + ScRange aFilterRange; + if( !(pFilterDBName->getAbsoluteRange( aFilterRange ) && (aFilterRange.aStart.Tab() == nSheet)) ) + return; + + // use the same name for the database range as used for the defined name '_FilterDatabase' + Reference< XDatabaseRange > xDatabaseRange = createUnnamedDatabaseRangeObject( aFilterRange ); + // first, try to create an auto filter + bool bHasAutoFilter = finalizeImport( xDatabaseRange ); + // no success: try to create an advanced filter + if( !(!bHasAutoFilter && xDatabaseRange.is()) ) + return; + + // the built-in defined name 'Criteria' must exist + const DefinedName* pCriteriaName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_CRITERIA, nSheet ).get(); + if( !pCriteriaName ) + return; + + ScRange aCriteriaRange; + if( !pCriteriaName->getAbsoluteRange( aCriteriaRange ) ) + return; + + // set some common properties for the filter descriptor + PropertySet aDescProps( xDatabaseRange->getFilterDescriptor() ); + aDescProps.setProperty( PROP_IsCaseSensitive, false ); + aDescProps.setProperty( PROP_SkipDuplicates, false ); + aDescProps.setProperty( PROP_Orientation, TableOrientation_ROWS ); + aDescProps.setProperty( PROP_ContainsHeader, true ); + // criteria range may contain wildcards, but these are incompatible with REs + aDescProps.setProperty( PROP_UseRegularExpressions, false ); + + // position of output data (if built-in defined name 'Extract' exists) + DefinedNameRef xExtractName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_EXTRACT, nSheet ); + ScRange aOutputRange; + bool bHasOutputRange = xExtractName && xExtractName->getAbsoluteRange( aOutputRange ); + aDescProps.setProperty( PROP_CopyOutputData, bHasOutputRange ); + if( bHasOutputRange ) { - ScRange aFilterRange; - if( pFilterDBName->getAbsoluteRange( aFilterRange ) && (aFilterRange.aStart.Tab() == nSheet) ) - { - // use the same name for the database range as used for the defined name '_FilterDatabase' - Reference< XDatabaseRange > xDatabaseRange = createUnnamedDatabaseRangeObject( aFilterRange ); - // first, try to create an auto filter - bool bHasAutoFilter = finalizeImport( xDatabaseRange ); - // no success: try to create an advanced filter - if( !bHasAutoFilter && xDatabaseRange.is() ) - { - // the built-in defined name 'Criteria' must exist - if( const DefinedName* pCriteriaName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_CRITERIA, nSheet ).get() ) - { - ScRange aCriteriaRange; - if( pCriteriaName->getAbsoluteRange( aCriteriaRange ) ) - { - // set some common properties for the filter descriptor - PropertySet aDescProps( xDatabaseRange->getFilterDescriptor() ); - aDescProps.setProperty( PROP_IsCaseSensitive, false ); - aDescProps.setProperty( PROP_SkipDuplicates, false ); - aDescProps.setProperty( PROP_Orientation, TableOrientation_ROWS ); - aDescProps.setProperty( PROP_ContainsHeader, true ); - // criteria range may contain wildcards, but these are incompatible with REs - aDescProps.setProperty( PROP_UseRegularExpressions, false ); - - // position of output data (if built-in defined name 'Extract' exists) - DefinedNameRef xExtractName = getDefinedNames().getByBuiltinId( BIFF_DEFNAME_EXTRACT, nSheet ); - ScRange aOutputRange; - bool bHasOutputRange = xExtractName && xExtractName->getAbsoluteRange( aOutputRange ); - aDescProps.setProperty( PROP_CopyOutputData, bHasOutputRange ); - if( bHasOutputRange ) - { - aDescProps.setProperty( PROP_SaveOutputPosition, true ); - aDescProps.setProperty( PROP_OutputPosition, CellAddress( aOutputRange.aStart.Tab(), aOutputRange.aStart.Col(), aOutputRange.aStart.Row() ) ); - } - - /* Properties of the database range (must be set after - modifying properties of the filter descriptor, - otherwise the 'FilterCriteriaSource' property gets - deleted). */ - PropertySet aRangeProps( xDatabaseRange ); - aRangeProps.setProperty( PROP_AutoFilter, false ); - aRangeProps.setProperty( PROP_FilterCriteriaSource, - CellRangeAddress( aCriteriaRange.aStart.Tab(), - aCriteriaRange.aStart.Col(), aCriteriaRange.aStart.Row(), - aCriteriaRange.aEnd.Col(), aCriteriaRange.aEnd.Row() )); - } - } - } - } + aDescProps.setProperty( PROP_SaveOutputPosition, true ); + aDescProps.setProperty( PROP_OutputPosition, CellAddress( aOutputRange.aStart.Tab(), aOutputRange.aStart.Col(), aOutputRange.aStart.Row() ) ); } + + /* Properties of the database range (must be set after + modifying properties of the filter descriptor, + otherwise the 'FilterCriteriaSource' property gets + deleted). */ + PropertySet aRangeProps( xDatabaseRange ); + aRangeProps.setProperty( PROP_AutoFilter, false ); + aRangeProps.setProperty( PROP_FilterCriteriaSource, + CellRangeAddress( aCriteriaRange.aStart.Tab(), + aCriteriaRange.aStart.Col(), aCriteriaRange.aStart.Row(), + aCriteriaRange.aEnd.Col(), aCriteriaRange.aEnd.Row() )); } bool AutoFilterBuffer::finalizeImport( const Reference< XDatabaseRange >& rxDatabaseRange ) diff --git a/sc/source/filter/oox/connectionsbuffer.cxx b/sc/source/filter/oox/connectionsbuffer.cxx index 165772fefc3a..c8a2b700a863 100644 --- a/sc/source/filter/oox/connectionsbuffer.cxx +++ b/sc/source/filter/oox/connectionsbuffer.cxx @@ -163,20 +163,20 @@ void Connection::importTables() void Connection::importTable( const AttributeList& rAttribs, sal_Int32 nElement ) { - if( maModel.mxWebPr ) + if( !maModel.mxWebPr ) + return; + + Any aTableAny; + switch( nElement ) { - Any aTableAny; - switch( nElement ) - { - case XLS_TOKEN( m ): break; - case XLS_TOKEN( s ): aTableAny <<= rAttribs.getXString( XML_v, OUString() ); break; - case XLS_TOKEN( x ): aTableAny <<= rAttribs.getInteger( XML_v, -1 ); break; - default: - OSL_ENSURE( false, "Connection::importTable - unexpected element" ); - return; - } - maModel.mxWebPr->maTables.push_back( aTableAny ); + case XLS_TOKEN( m ): break; + case XLS_TOKEN( s ): aTableAny <<= rAttribs.getXString( XML_v, OUString() ); break; + case XLS_TOKEN( x ): aTableAny <<= rAttribs.getInteger( XML_v, -1 ); break; + default: + OSL_ENSURE( false, "Connection::importTable - unexpected element" ); + return; } + maModel.mxWebPr->maTables.push_back( aTableAny ); } void Connection::importConnection( SequenceInputStream& rStrm ) @@ -259,20 +259,20 @@ void Connection::importWebPrTables( SequenceInputStream& /*rStrm*/ ) void Connection::importWebPrTable( SequenceInputStream& rStrm, sal_Int32 nRecId ) { - if( maModel.mxWebPr ) + if( !maModel.mxWebPr ) + return; + + Any aTableAny; + switch( nRecId ) { - Any aTableAny; - switch( nRecId ) - { - case BIFF12_ID_PCITEM_MISSING: break; - case BIFF12_ID_PCITEM_STRING: aTableAny <<= BiffHelper::readString( rStrm ); break; - case BIFF12_ID_PCITEM_INDEX: aTableAny <<= rStrm.readInt32(); break; - default: - OSL_ENSURE( false, "Connection::importWebPrTable - unexpected record" ); - return; - } - maModel.mxWebPr->maTables.push_back( aTableAny ); + case BIFF12_ID_PCITEM_MISSING: break; + case BIFF12_ID_PCITEM_STRING: aTableAny <<= BiffHelper::readString( rStrm ); break; + case BIFF12_ID_PCITEM_INDEX: aTableAny <<= rStrm.readInt32(); break; + default: + OSL_ENSURE( false, "Connection::importWebPrTable - unexpected record" ); + return; } + maModel.mxWebPr->maTables.push_back( aTableAny ); } ConnectionsBuffer::ConnectionsBuffer( const WorkbookHelper& rHelper ) : diff --git a/sc/source/filter/oox/defnamesbuffer.cxx b/sc/source/filter/oox/defnamesbuffer.cxx index 2bf5d5c4c0ac..ed2b041dcd0f 100644 --- a/sc/source/filter/oox/defnamesbuffer.cxx +++ b/sc/source/filter/oox/defnamesbuffer.cxx @@ -272,52 +272,55 @@ void DefinedName::convertFormula( const css::uno::Sequence<css::sheet::ExternalL Sequence< FormulaToken > aFTokenSeq; ScTokenConversion::ConvertToTokenSequence( getScDocument(), aFTokenSeq, *pTokenArray ); // set built-in names (print ranges, repeated titles, filter ranges) - if( !isGlobalName() ) switch( mcBuiltinId ) + if( isGlobalName() ) + return; + + switch( mcBuiltinId ) { - case BIFF_DEFNAME_PRINTAREA: - { - Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); - ScRangeList aPrintRanges; - getFormulaParser().extractCellRangeList( aPrintRanges, aFTokenSeq, mnCalcSheet ); - if( xPrintAreas.is() && !aPrintRanges.empty() ) - xPrintAreas->setPrintAreas( AddressConverter::toApiSequence(aPrintRanges) ); - } - break; - case BIFF_DEFNAME_PRINTTITLES: + case BIFF_DEFNAME_PRINTAREA: + { + Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); + ScRangeList aPrintRanges; + getFormulaParser().extractCellRangeList( aPrintRanges, aFTokenSeq, mnCalcSheet ); + if( xPrintAreas.is() && !aPrintRanges.empty() ) + xPrintAreas->setPrintAreas( AddressConverter::toApiSequence(aPrintRanges) ); + } + break; + case BIFF_DEFNAME_PRINTTITLES: + { + Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); + ScRangeList aTitleRanges; + getFormulaParser().extractCellRangeList( aTitleRanges, aFTokenSeq, mnCalcSheet ); + if( xPrintAreas.is() && !aTitleRanges.empty() ) { - Reference< XPrintAreas > xPrintAreas( getSheetFromDoc( mnCalcSheet ), UNO_QUERY ); - ScRangeList aTitleRanges; - getFormulaParser().extractCellRangeList( aTitleRanges, aFTokenSeq, mnCalcSheet ); - if( xPrintAreas.is() && !aTitleRanges.empty() ) + bool bHasRowTitles = false; + bool bHasColTitles = false; + const ScAddress& rMaxPos = getAddressConverter().getMaxAddress(); + for (size_t i = 0, nSize = aTitleRanges.size(); i < nSize; ++i) { - bool bHasRowTitles = false; - bool bHasColTitles = false; - const ScAddress& rMaxPos = getAddressConverter().getMaxAddress(); - for (size_t i = 0, nSize = aTitleRanges.size(); i < nSize; ++i) + const ScRange& rRange = aTitleRanges[i]; + bool bFullRow = (rRange.aStart.Col() == 0) && ( rRange.aEnd.Col() >= rMaxPos.Col() ); + bool bFullCol = (rRange.aStart.Row() == 0) && ( rRange.aEnd.Row() >= rMaxPos.Row() ); + if( !bHasRowTitles && bFullRow && !bFullCol ) { - const ScRange& rRange = aTitleRanges[i]; - bool bFullRow = (rRange.aStart.Col() == 0) && ( rRange.aEnd.Col() >= rMaxPos.Col() ); - bool bFullCol = (rRange.aStart.Row() == 0) && ( rRange.aEnd.Row() >= rMaxPos.Row() ); - if( !bHasRowTitles && bFullRow && !bFullCol ) - { - xPrintAreas->setTitleRows( CellRangeAddress(rRange.aStart.Tab(), - rRange.aStart.Col(), rRange.aStart.Row(), - rRange.aEnd.Col(), rRange.aEnd.Row()) ); - xPrintAreas->setPrintTitleRows( true ); - bHasRowTitles = true; - } - else if( !bHasColTitles && bFullCol && !bFullRow ) - { - xPrintAreas->setTitleColumns( CellRangeAddress(rRange.aStart.Tab(), - rRange.aStart.Col(), rRange.aStart.Row(), - rRange.aEnd.Col(), rRange.aEnd.Row()) ); - xPrintAreas->setPrintTitleColumns( true ); - bHasColTitles = true; - } + xPrintAreas->setTitleRows( CellRangeAddress(rRange.aStart.Tab(), + rRange.aStart.Col(), rRange.aStart.Row(), + rRange.aEnd.Col(), rRange.aEnd.Row()) ); + xPrintAreas->setPrintTitleRows( true ); + bHasRowTitles = true; + } + else if( !bHasColTitles && bFullCol && !bFullRow ) + { + xPrintAreas->setTitleColumns( CellRangeAddress(rRange.aStart.Tab(), + rRange.aStart.Col(), rRange.aStart.Row(), + rRange.aEnd.Col(), rRange.aEnd.Row()) ); + xPrintAreas->setPrintTitleColumns( true ); + bHasColTitles = true; } } } - break; + } + break; } } diff --git a/sc/source/filter/oox/drawingfragment.cxx b/sc/source/filter/oox/drawingfragment.cxx index 396170be35e3..83b3a7446f5e 100644 --- a/sc/source/filter/oox/drawingfragment.cxx +++ b/sc/source/filter/oox/drawingfragment.cxx @@ -671,25 +671,26 @@ void VmlDrawing::notifyXShapeInserted( const Reference< XShape >& rxShape, extendShapeBoundingBox( rShapeRect ); // convert settings from VML client data - if( const ::oox::vml::ClientData* pClientData = rShape.getClientData() ) + const ::oox::vml::ClientData* pClientData = rShape.getClientData(); + if(!pClientData) + return; + + // specific settings for embedded form controls + try { - // specific settings for embedded form controls - try - { - Reference< XControlShape > xCtrlShape( rxShape, UNO_QUERY_THROW ); - Reference< XControlModel > xCtrlModel( xCtrlShape->getControl(), UNO_SET_THROW ); - PropertySet aPropSet( xCtrlModel ); + Reference< XControlShape > xCtrlShape( rxShape, UNO_QUERY_THROW ); + Reference< XControlModel > xCtrlModel( xCtrlShape->getControl(), UNO_SET_THROW ); + PropertySet aPropSet( xCtrlModel ); - // printable - aPropSet.setProperty( PROP_Printable, pClientData->mbPrintObject ); + // printable + aPropSet.setProperty( PROP_Printable, pClientData->mbPrintObject ); - // control source links - if( !pClientData->maFmlaLink.isEmpty() || !pClientData->maFmlaRange.isEmpty() ) - maControlConv.bindToSources( xCtrlModel, pClientData->maFmlaLink, pClientData->maFmlaRange, getSheetIndex() ); - } - catch( Exception& ) - { - } + // control source links + if( !pClientData->maFmlaLink.isEmpty() || !pClientData->maFmlaRange.isEmpty() ) + maControlConv.bindToSources( xCtrlModel, pClientData->maFmlaLink, pClientData->maFmlaRange, getSheetIndex() ); + } + catch( Exception& ) + { } } diff --git a/sc/source/filter/oox/excelvbaproject.cxx b/sc/source/filter/oox/excelvbaproject.cxx index 8a9a3074a167..c3e48ba474c1 100644 --- a/sc/source/filter/oox/excelvbaproject.cxx +++ b/sc/source/filter/oox/excelvbaproject.cxx @@ -63,7 +63,10 @@ void ExcelVbaProject::prepareImport() { /* Check if the sheets have imported codenames. Generate new unused codenames if not. */ - if( mxDocument.is() ) try + if( !mxDocument.is() ) + return; + + try { // collect existing codenames (do not use them when creating new codenames) ::std::set< OUString > aUsedCodeNames; diff --git a/sc/source/filter/oox/externallinkfragment.cxx b/sc/source/filter/oox/externallinkfragment.cxx index eddc0c607cbd..07fbece61698 100644 --- a/sc/source/filter/oox/externallinkfragment.cxx +++ b/sc/source/filter/oox/externallinkfragment.cxx @@ -63,23 +63,23 @@ ContextHandlerRef ExternalSheetDataContext::onCreateContext( sal_Int32 nElement, void ExternalSheetDataContext::onCharacters( const OUString& rChars ) { - if( isCurrentElement( XLS_TOKEN( v ) ) ) + if( !isCurrentElement( XLS_TOKEN( v ) ) ) + return; + + switch( mnCurrType ) { - switch( mnCurrType ) - { - case XML_b: - case XML_n: - setCellValue( Any( rChars.toDouble() ) ); - break; - case XML_e: - setCellValue( Any( BiffHelper::calcDoubleFromError( getUnitConverter().calcBiffErrorCode( rChars ) ) ) ); - break; - case XML_str: - setCellValue( Any( rChars ) ); - break; - } - mnCurrType = XML_TOKEN_INVALID; + case XML_b: + case XML_n: + setCellValue( Any( rChars.toDouble() ) ); + break; + case XML_e: + setCellValue( Any( BiffHelper::calcDoubleFromError( getUnitConverter().calcBiffErrorCode( rChars ) ) ) ); + break; + case XML_str: + setCellValue( Any( rChars ) ); + break; } + mnCurrType = XML_TOKEN_INVALID; } ContextHandlerRef ExternalSheetDataContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm ) @@ -246,7 +246,10 @@ void ExternalLinkFragment::onCharacters( const OUString& rChars ) void ExternalLinkFragment::onEndElement() { - if( isCurrentElement( XLS_TOKEN( value ) ) && mxExtName ) switch( mnResultType ) + if( !(isCurrentElement( XLS_TOKEN( value ) ) && mxExtName) ) + return; + + switch( mnResultType ) { case XML_b: mxExtName->appendResultValue( maResultValue.toDouble() ); diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx index 9eb33e8e3308..afd418acaf85 100644 --- a/sc/source/filter/oox/formulabase.cxx +++ b/sc/source/filter/oox/formulabase.cxx @@ -1149,7 +1149,10 @@ private: OpCodeProviderImpl::OpCodeProviderImpl( const FunctionInfoVector& rFuncInfos, const Reference< XMultiServiceFactory >& rxModelFactory ) { - if( rxModelFactory.is() ) try + if( !rxModelFactory.is() ) + return; + + try { Reference< XFormulaOpCodeMapper > xMapper( rxModelFactory->createInstance( "com.sun.star.sheet.FormulaOpCodeMapper" ), UNO_QUERY_THROW ); @@ -1684,24 +1687,24 @@ void FormulaProcessorBase::convertStringToStringList( ApiTokenSequence& orTokens, sal_Unicode cStringSep, bool bTrimLeadingSpaces ) const { OUString aString; - if( extractString( aString, orTokens ) && !aString.isEmpty() ) + if( !(extractString( aString, orTokens ) && !aString.isEmpty()) ) + return; + + ::std::vector< ApiToken > aNewTokens; + for( sal_Int32 nPos{ 0 }; nPos>=0; ) { - ::std::vector< ApiToken > aNewTokens; - for( sal_Int32 nPos{ 0 }; nPos>=0; ) + OUString aEntry = aString.getToken( 0, cStringSep, nPos ); + if( bTrimLeadingSpaces ) { - OUString aEntry = aString.getToken( 0, cStringSep, nPos ); - if( bTrimLeadingSpaces ) - { - sal_Int32 nStart = 0; - while( (nStart < aEntry.getLength()) && (aEntry[ nStart ] == ' ') ) ++nStart; - aEntry = aEntry.copy( nStart ); - } - if( !aNewTokens.empty() ) - aNewTokens.emplace_back( OPCODE_SEP, Any() ); - aNewTokens.emplace_back( OPCODE_PUSH, Any( aEntry ) ); + sal_Int32 nStart = 0; + while( (nStart < aEntry.getLength()) && (aEntry[ nStart ] == ' ') ) ++nStart; + aEntry = aEntry.copy( nStart ); } - orTokens = ContainerHelper::vectorToSequence( aNewTokens ); + if( !aNewTokens.empty() ) + aNewTokens.emplace_back( OPCODE_SEP, Any() ); + aNewTokens.emplace_back( OPCODE_PUSH, Any( aEntry ) ); } + orTokens = ContainerHelper::vectorToSequence( aNewTokens ); } } // namespace oox diff --git a/sc/source/filter/oox/pagesettings.cxx b/sc/source/filter/oox/pagesettings.cxx index b1854659f4ac..8965d78974b7 100644 --- a/sc/source/filter/oox/pagesettings.cxx +++ b/sc/source/filter/oox/pagesettings.cxx @@ -1012,26 +1012,26 @@ void PageSettingsConverter::convertHeaderFooterData( orHFData.mbShareOddEven = !bUseEvenContent; orHFData.mbDynamicHeight = true; - if( orHFData.mbHasContent ) - { - // use maximum height of odd/even header/footer - orHFData.mnHeight = ::std::max( nOddHeight, nEvenHeight ); - /* Calc contains distance between bottom of header and top of page - body in "HeaderBodyDistance" property, and distance between bottom - of page body and top of footer in "FooterBodyDistance" property */ - orHFData.mnBodyDist = getUnitConverter().scaleToMm100( fPageMargin - fContentMargin, Unit::Inch ) - orHFData.mnHeight; - /* #i23296# Distance less than 0 means, header or footer overlays page - body. As this is not possible in Calc, set fixed header or footer - height (crop header/footer) to get correct top position of page body. */ - orHFData.mbDynamicHeight = orHFData.mnBodyDist >= 0; - /* "HeaderHeight" property is in fact distance from top of header to - top of page body (including "HeaderBodyDistance"). - "FooterHeight" property is in fact distance from bottom of page - body to bottom of footer (including "FooterBodyDistance"). */ - orHFData.mnHeight += orHFData.mnBodyDist; - // negative body distance not allowed - orHFData.mnBodyDist = ::std::max< sal_Int32 >( orHFData.mnBodyDist, 0 ); - } + if( !orHFData.mbHasContent ) + return; + + // use maximum height of odd/even header/footer + orHFData.mnHeight = ::std::max( nOddHeight, nEvenHeight ); + /* Calc contains distance between bottom of header and top of page + body in "HeaderBodyDistance" property, and distance between bottom + of page body and top of footer in "FooterBodyDistance" property */ + orHFData.mnBodyDist = getUnitConverter().scaleToMm100( fPageMargin - fContentMargin, Unit::Inch ) - orHFData.mnHeight; + /* #i23296# Distance less than 0 means, header or footer overlays page + body. As this is not possible in Calc, set fixed header or footer + height (crop header/footer) to get correct top position of page body. */ + orHFData.mbDynamicHeight = orHFData.mnBodyDist >= 0; + /* "HeaderHeight" property is in fact distance from top of header to + top of page body (including "HeaderBodyDistance"). + "FooterHeight" property is in fact distance from bottom of page + body to bottom of footer (including "FooterBodyDistance"). */ + orHFData.mnHeight += orHFData.mnBodyDist; + // negative body distance not allowed + orHFData.mnBodyDist = ::std::max< sal_Int32 >( orHFData.mnBodyDist, 0 ); } sal_Int32 PageSettingsConverter::writeHeaderFooter( diff --git a/sc/source/filter/oox/pivotcachebuffer.cxx b/sc/source/filter/oox/pivotcachebuffer.cxx index e80605b9c130..cd72bb418b83 100644 --- a/sc/source/filter/oox/pivotcachebuffer.cxx +++ b/sc/source/filter/oox/pivotcachebuffer.cxx @@ -816,21 +816,21 @@ void PivotCacheField::importPCRecordItem( SequenceInputStream& rStrm, const Work void PivotCacheField::writeItemToSourceDataCell( const WorksheetHelper& rSheetHelper, sal_Int32 nCol, sal_Int32 nRow, const PivotCacheItem& rItem ) { - if( rItem.getType() != XML_m ) + if( rItem.getType() == XML_m ) + return; + + CellModel aModel; + aModel.maCellAddr = ScAddress( SCCOL( nCol ), SCROW( nRow ), rSheetHelper.getSheetIndex() ); + SheetDataBuffer& rSheetData = rSheetHelper.getSheetData(); + switch( rItem.getType() ) { - CellModel aModel; - aModel.maCellAddr = ScAddress( SCCOL( nCol ), SCROW( nRow ), rSheetHelper.getSheetIndex() ); - SheetDataBuffer& rSheetData = rSheetHelper.getSheetData(); - switch( rItem.getType() ) - { - case XML_s: rSheetData.setStringCell( aModel, rItem.getValue().get< OUString >() ); break; - case XML_n: rSheetData.setValueCell( aModel, rItem.getValue().get< double >() ); break; - case XML_i: rSheetData.setValueCell( aModel, rItem.getValue().get< sal_Int16 >() ); break; - case XML_d: rSheetData.setDateTimeCell( aModel, rItem.getValue().get< css::util::DateTime >() ); break; - case XML_b: rSheetData.setBooleanCell( aModel, rItem.getValue().get< bool >() ); break; - case XML_e: rSheetData.setErrorCell( aModel, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break; - default: OSL_FAIL( "PivotCacheField::writeItemToSourceDataCell - unexpected item data type" ); - } + case XML_s: rSheetData.setStringCell( aModel, rItem.getValue().get< OUString >() ); break; + case XML_n: rSheetData.setValueCell( aModel, rItem.getValue().get< double >() ); break; + case XML_i: rSheetData.setValueCell( aModel, rItem.getValue().get< sal_Int16 >() ); break; + case XML_d: rSheetData.setDateTimeCell( aModel, rItem.getValue().get< css::util::DateTime >() ); break; + case XML_b: rSheetData.setBooleanCell( aModel, rItem.getValue().get< bool >() ); break; + case XML_e: rSheetData.setErrorCell( aModel, static_cast< sal_uInt8 >( rItem.getValue().get< sal_Int32 >() ) ); break; + default: OSL_FAIL( "PivotCacheField::writeItemToSourceDataCell - unexpected item data type" ); } } diff --git a/sc/source/filter/oox/pivotcachefragment.cxx b/sc/source/filter/oox/pivotcachefragment.cxx index 1b7e2d36b090..a8db4426be33 100644 --- a/sc/source/filter/oox/pivotcachefragment.cxx +++ b/sc/source/filter/oox/pivotcachefragment.cxx @@ -300,23 +300,23 @@ void PivotCacheRecordsFragment::importPCRecord( SequenceInputStream& rStrm ) void PivotCacheRecordsFragment::importPCRecordItem( sal_Int32 nRecId, SequenceInputStream& rStrm ) { - if( mbInRecord ) + if( !mbInRecord ) + return; + + PivotCacheItem aItem; + switch( nRecId ) { - PivotCacheItem aItem; - switch( nRecId ) - { - case BIFF12_ID_PCITEM_MISSING: break; - case BIFF12_ID_PCITEM_STRING: aItem.readString( rStrm ); break; - case BIFF12_ID_PCITEM_DOUBLE: aItem.readDouble( rStrm ); break; - case BIFF12_ID_PCITEM_DATE: aItem.readDate( rStrm ); break; - case BIFF12_ID_PCITEM_BOOL: aItem.readBool( rStrm ); break; - case BIFF12_ID_PCITEM_ERROR: aItem.readError( rStrm ); break; - case BIFF12_ID_PCITEM_INDEX: aItem.readIndex( rStrm ); break; - default: OSL_FAIL( "OoxPivotCacheRecordsFragment::importPCRecordItem - unexpected record" ); - } - mrPivotCache.writeSourceDataCell( *this, mnColIdx, mnRowIdx, aItem ); - ++mnColIdx; + case BIFF12_ID_PCITEM_MISSING: break; + case BIFF12_ID_PCITEM_STRING: aItem.readString( rStrm ); break; + case BIFF12_ID_PCITEM_DOUBLE: aItem.readDouble( rStrm ); break; + case BIFF12_ID_PCITEM_DATE: aItem.readDate( rStrm ); break; + case BIFF12_ID_PCITEM_BOOL: aItem.readBool( rStrm ); break; + case BIFF12_ID_PCITEM_ERROR: aItem.readError( rStrm ); break; + case BIFF12_ID_PCITEM_INDEX: aItem.readIndex( rStrm ); break; + default: OSL_FAIL( "OoxPivotCacheRecordsFragment::importPCRecordItem - unexpected record" ); } + mrPivotCache.writeSourceDataCell( *this, mnColIdx, mnRowIdx, aItem ); + ++mnColIdx; } diff --git a/sc/source/filter/oox/pivottablebuffer.cxx b/sc/source/filter/oox/pivottablebuffer.cxx index 8bfa5f206ed3..23889b790774 100644 --- a/sc/source/filter/oox/pivottablebuffer.cxx +++ b/sc/source/filter/oox/pivottablebuffer.cxx @@ -382,7 +382,10 @@ void PivotTableField::finalizeImport( const Reference< XDataPilotDescriptor >& r returns -1 for all fields not based on source data. */ Reference< XDataPilotField > xDPField; sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex ); - if( (nDatabaseIdx >= 0) && rxDPDesc.is() ) try + if( !((nDatabaseIdx >= 0) && rxDPDesc.is()) ) + return; + + try { // try to get the source field and its name from passed DataPilot descriptor Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW ); @@ -443,29 +446,30 @@ void PivotTableField::finalizeDateGroupingImport( const Reference< XDataPilotFie void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, const PivotCacheField& rBaseCacheField, PivotCacheGroupItemVector& orItemNames ) { - if( maDPFieldName.isEmpty() ) // prevent endless loops if file format is broken + if( !maDPFieldName.isEmpty() ) // prevent endless loops if file format is broken + return; + + PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ); + if( !pCacheField ) + return; + + // data field can have user defined groupname captions, apply them + // if they do + IdCaptionPairList captionList; + for( const auto& rItem : maItems ) { - if( PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) - { - // data field can have user defined groupname captions, apply them - // if they do - IdCaptionPairList captionList; - for( const auto& rItem : maItems ) - { - if ( rItem.mnType == XML_data && rItem.msCaption.getLength() ) - captionList.emplace_back( rItem.mnCacheItem, rItem.msCaption ); - } - if ( !captionList.empty() ) - pCacheField->applyItemCaptions( captionList ); - - maDPFieldName = pCacheField->createParentGroupField( rxBaseDPField, rBaseCacheField, orItemNames ); - pCacheField->setFinalGroupName(maDPFieldName); - // on success, try to create nested group fields - Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName ); - if( xDPField.is() ) - mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, orItemNames ); - } + if ( rItem.mnType == XML_data && rItem.msCaption.getLength() ) + captionList.emplace_back( rItem.mnCacheItem, rItem.msCaption ); } + if ( !captionList.empty() ) + pCacheField->applyItemCaptions( captionList ); + + maDPFieldName = pCacheField->createParentGroupField( rxBaseDPField, rBaseCacheField, orItemNames ); + pCacheField->setFinalGroupName(maDPFieldName); + // on success, try to create nested group fields + Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName ); + if( xDPField.is() ) + mrPivotTable.finalizeParentGroupingImport( xDPField, *pCacheField, orItemNames ); } void PivotTableField::finalizeImportBasedOnCache( const Reference< XDataPilotDescriptor >& rxDPDesc) @@ -516,50 +520,50 @@ void PivotTableField::convertPageField( const PTPageFieldModel& rPageField ) // convert all settings common for row/column/page fields Reference< XDataPilotField > xDPField = convertRowColPageField( XML_axisPage ); - if( xDPField.is() ) - { - PropertySet aPropSet( xDPField ); + if( !xDPField.is() ) + return; + + PropertySet aPropSet( xDPField ); - // find cache item used as 'selected page' - sal_Int32 nCacheItem = -1; - if( maModel.mbMultiPageItems ) + // find cache item used as 'selected page' + sal_Int32 nCacheItem = -1; + if( maModel.mbMultiPageItems ) + { + // multiple items may be selected + OSL_ENSURE( rPageField.mnItem == BIFF12_PTPAGEFIELD_MULTIITEMS, "PivotTableField::convertPageField - unexpected cache item index" ); + // try to find a single visible item + bool bHasMultiItems = false; + for( const auto& rItem : maItems ) { - // multiple items may be selected - OSL_ENSURE( rPageField.mnItem == BIFF12_PTPAGEFIELD_MULTIITEMS, "PivotTableField::convertPageField - unexpected cache item index" ); - // try to find a single visible item - bool bHasMultiItems = false; - for( const auto& rItem : maItems ) + if( (rItem.mnType == XML_data) && !rItem.mbHidden ) { - if( (rItem.mnType == XML_data) && !rItem.mbHidden ) - { - bHasMultiItems = nCacheItem >= 0; - nCacheItem = bHasMultiItems ? -1 : rItem.mnCacheItem; - } - - if( bHasMultiItems ) - break; + bHasMultiItems = nCacheItem >= 0; + nCacheItem = bHasMultiItems ? -1 : rItem.mnCacheItem; } + + if( bHasMultiItems ) + break; } - else - { - // single item may be selected - if( (0 <= rPageField.mnItem) && (rPageField.mnItem < static_cast< sal_Int32 >( maItems.size() )) ) - nCacheItem = maItems[ rPageField.mnItem ].mnCacheItem; - } + } + else + { + // single item may be selected + if( (0 <= rPageField.mnItem) && (rPageField.mnItem < static_cast< sal_Int32 >( maItems.size() )) ) + nCacheItem = maItems[ rPageField.mnItem ].mnCacheItem; + } - if( nCacheItem >= 0 ) + if( nCacheItem < 0 ) + return; + + if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) + { + if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( nCacheItem ) ) { - if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) ) - { - if( const PivotCacheItem* pSharedItem = pCacheField->getCacheItem( nCacheItem ) ) - { - ScDPObject* pDPObj = mrPivotTable.getDPObject(); - ScDPSaveData* pSaveData = pDPObj->GetSaveData(); - ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(pCacheField->getName()); - OUString aSelectedPage = pSharedItem->getFormattedName(*pDim, pDPObj, DateTime(getWorkbookSettings().getNullDate())); - aPropSet.setProperty( PROP_SelectedPage, aSelectedPage ); - } - } + ScDPObject* pDPObj = mrPivotTable.getDPObject(); + ScDPSaveData* pSaveData = pDPObj->GetSaveData(); + ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(pCacheField->getName()); + OUString aSelectedPage = pSharedItem->getFormattedName(*pDim, pDPObj, DateTime(getWorkbookSettings().getNullDate())); + aPropSet.setProperty( PROP_SelectedPage, aSelectedPage ); } } } @@ -569,75 +573,76 @@ void PivotTableField::convertDataField( const PTDataFieldModel& rDataField ) OSL_ENSURE( rDataField.mnField == mnFieldIndex, "PivotTableField::convertDataField - wrong field index" ); OSL_ENSURE( maModel.mbDataField, "PivotTableField::convertDataField - not a data field" ); Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName ); - if( xDPField.is() ) + if( !xDPField.is() ) + return; + + PropertySet aPropSet( xDPField ); + + // field orientation + aPropSet.setProperty( PROP_Orientation, DataPilotFieldOrientation_DATA ); + + if (!rDataField.maName.isEmpty()) + aPropSet.setProperty(PROP_Name, rDataField.maName); + + /* Field aggregation function. Documentation is a little bit confused + about which names to use for the count functions. The name 'count' + means 'count all', and 'countNum' means 'count numbers'. On the + other hand, for subtotals, 'countA' means 'count all', and 'count' + means 'count numbers' (see above). */ + GeneralFunction eAggFunc = GeneralFunction_SUM; + switch( rDataField.mnSubtotal ) { - PropertySet aPropSet( xDPField ); + case XML_sum: eAggFunc = GeneralFunction_SUM; break; + case XML_count: eAggFunc = GeneralFunction_COUNT; break; + case XML_average: eAggFunc = GeneralFunction_AVERAGE; break; + case XML_max: eAggFunc = GeneralFunction_MAX; break; + case XML_min: eAggFunc = GeneralFunction_MIN; break; + case XML_product: eAggFunc = GeneralFunction_PRODUCT; break; + case XML_countNums: eAggFunc = GeneralFunction_COUNTNUMS; break; + case XML_stdDev: eAggFunc = GeneralFunction_STDEV; break; + case XML_stdDevp: eAggFunc = GeneralFunction_STDEVP; break; + case XML_var: eAggFunc = GeneralFunction_VAR; break; + case XML_varp: eAggFunc = GeneralFunction_VARP; break; + default: OSL_FAIL( "PivotTableField::convertDataField - unknown aggregation function" ); + } + aPropSet.setProperty( PROP_Function, eAggFunc ); - // field orientation - aPropSet.setProperty( PROP_Orientation, DataPilotFieldOrientation_DATA ); - - if (!rDataField.maName.isEmpty()) - aPropSet.setProperty(PROP_Name, rDataField.maName); - - /* Field aggregation function. Documentation is a little bit confused - about which names to use for the count functions. The name 'count' - means 'count all', and 'countNum' means 'count numbers'. On the - other hand, for subtotals, 'countA' means 'count all', and 'count' - means 'count numbers' (see above). */ - GeneralFunction eAggFunc = GeneralFunction_SUM; - switch( rDataField.mnSubtotal ) - { - case XML_sum: eAggFunc = GeneralFunction_SUM; break; - case XML_count: eAggFunc = GeneralFunction_COUNT; break; - case XML_average: eAggFunc = GeneralFunction_AVERAGE; break; - case XML_max: eAggFunc = GeneralFunction_MAX; break; - case XML_min: eAggFunc = GeneralFunction_MIN; break; - case XML_product: eAggFunc = GeneralFunction_PRODUCT; break; - case XML_countNums: eAggFunc = GeneralFunction_COUNTNUMS; break; - case XML_stdDev: eAggFunc = GeneralFunction_STDEV; break; - case XML_stdDevp: eAggFunc = GeneralFunction_STDEVP; break; - case XML_var: eAggFunc = GeneralFunction_VAR; break; - case XML_varp: eAggFunc = GeneralFunction_VARP; break; - default: OSL_FAIL( "PivotTableField::convertDataField - unknown aggregation function" ); - } - aPropSet.setProperty( PROP_Function, eAggFunc ); + // field reference ('show data as') + DataPilotFieldReference aReference; + aReference.ReferenceType = DataPilotFieldReferenceType::NONE; + switch( rDataField.mnShowDataAs ) + { + case XML_difference: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_DIFFERENCE; break; + case XML_percent: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE; break; + case XML_percentDiff: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE; break; + case XML_runTotal: aReference.ReferenceType = DataPilotFieldReferenceType::RUNNING_TOTAL; break; + case XML_percentOfRow: aReference.ReferenceType = DataPilotFieldReferenceType::ROW_PERCENTAGE; break; + case XML_percentOfCol: aReference.ReferenceType = DataPilotFieldReferenceType::COLUMN_PERCENTAGE; break; + case XML_percentOfTotal: aReference.ReferenceType = DataPilotFieldReferenceType::TOTAL_PERCENTAGE; break; + case XML_index: aReference.ReferenceType = DataPilotFieldReferenceType::INDEX; break; + } + if( aReference.ReferenceType == DataPilotFieldReferenceType::NONE ) + return; - // field reference ('show data as') - DataPilotFieldReference aReference; - aReference.ReferenceType = DataPilotFieldReferenceType::NONE; - switch( rDataField.mnShowDataAs ) - { - case XML_difference: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_DIFFERENCE; break; - case XML_percent: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE; break; - case XML_percentDiff: aReference.ReferenceType = DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE; break; - case XML_runTotal: aReference.ReferenceType = DataPilotFieldReferenceType::RUNNING_TOTAL; break; - case XML_percentOfRow: aReference.ReferenceType = DataPilotFieldReferenceType::ROW_PERCENTAGE; break; - case XML_percentOfCol: aReference.ReferenceType = DataPilotFieldReferenceType::COLUMN_PERCENTAGE; break; - case XML_percentOfTotal: aReference.ReferenceType = DataPilotFieldReferenceType::TOTAL_PERCENTAGE; break; - case XML_index: aReference.ReferenceType = DataPilotFieldReferenceType::INDEX; break; - } - if( aReference.ReferenceType != DataPilotFieldReferenceType::NONE ) - { - if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( rDataField.mnBaseField ) ) - { - aReference.ReferenceField = pCacheField->getName(); - switch( rDataField.mnBaseItem ) - { - case OOX_PT_PREVIOUS_ITEM: - aReference.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS; - break; - case OOX_PT_NEXT_ITEM: - aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT; - break; - default: - aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED; - if( const PivotCacheItem* pCacheItem = pCacheField->getCacheItem( rDataField.mnBaseItem ) ) - aReference.ReferenceItemName = pCacheItem->getName(); - } - aPropSet.setProperty( PROP_Reference, aReference ); - } - } + const PivotCacheField* pCacheField = mrPivotTable.getCacheField( rDataField.mnBaseField ); + if( !pCacheField ) + return; + + aReference.ReferenceField = pCacheField->getName(); + switch( rDataField.mnBaseItem ) + { + case OOX_PT_PREVIOUS_ITEM: + aReference.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS; + break; + case OOX_PT_NEXT_ITEM: + aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT; + break; + default: + aReference.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED; + if( const PivotCacheItem* pCacheItem = pCacheField->getCacheItem( rDataField.mnBaseItem ) ) + aReference.ReferenceItemName = pCacheItem->getName(); } + aPropSet.setProperty( PROP_Reference, aReference ); } // private -------------------------------------------------------------------- @@ -880,19 +885,19 @@ void PivotTableFilter::importTop10Filter( SequenceInputStream& rStrm ) void PivotTableFilter::finalizeImport() { // only simple top10 filter supported - if( maModel.mnType == XML_count ) + if( maModel.mnType != XML_count ) + return; + + PropertySet aPropSet( mrPivotTable.getDataPilotField( maModel.mnField ) ); + if( aPropSet.is() ) { - PropertySet aPropSet( mrPivotTable.getDataPilotField( maModel.mnField ) ); - if( aPropSet.is() ) - { - DataPilotFieldAutoShowInfo aAutoShowInfo; - aAutoShowInfo.IsEnabled = true; - aAutoShowInfo.ShowItemsMode = maModel.mbTopFilter ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM; - aAutoShowInfo.ItemCount = getLimitedValue< sal_Int32, double >( maModel.mfValue, 0, SAL_MAX_INT32 ); - if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnMeasureField ) ) - aAutoShowInfo.DataField = pCacheField->getName(); - aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo ); - } + DataPilotFieldAutoShowInfo aAutoShowInfo; + aAutoShowInfo.IsEnabled = true; + aAutoShowInfo.ShowItemsMode = maModel.mbTopFilter ? DataPilotFieldShowItemsMode::FROM_TOP : DataPilotFieldShowItemsMode::FROM_BOTTOM; + aAutoShowInfo.ItemCount = getLimitedValue< sal_Int32, double >( maModel.mfValue, 0, SAL_MAX_INT32 ); + if( const PivotCacheField* pCacheField = mrPivotTable.getCacheFieldOfDataField( maModel.mnMeasureField ) ) + aAutoShowInfo.DataField = pCacheField->getName(); + aPropSet.setProperty( PROP_AutoShowInfo, aAutoShowInfo ); } } @@ -1199,116 +1204,116 @@ PivotTableFilter& PivotTable::createTableFilter() void PivotTable::finalizeImport() { - if( getAddressConverter().validateCellRange( maLocationModel.maRange, true, true ) ) + if( !getAddressConverter().validateCellRange( maLocationModel.maRange, true, true ) ) + return; + + mpPivotCache = getPivotCaches().importPivotCacheFragment( maDefModel.mnCacheId ); + if( !(mpPivotCache && mpPivotCache->isValidDataSource() && !maDefModel.maName.isEmpty()) ) + return; + + // clear destination area of the original pivot table + try + { + Reference< XSheetOperation > xSheetOp( getCellRangeFromDoc( maLocationModel.maRange ), UNO_QUERY_THROW ); + using namespace ::com::sun::star::sheet::CellFlags; + xSheetOp->clearContents( VALUE | DATETIME | STRING | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED ); + } + catch( Exception& ) { - mpPivotCache = getPivotCaches().importPivotCacheFragment( maDefModel.mnCacheId ); - if( mpPivotCache && mpPivotCache->isValidDataSource() && !maDefModel.maName.isEmpty() ) + } + + try + { + // create a new data pilot descriptor based on the source data + Reference< XDataPilotTablesSupplier > xDPTablesSupp( getSheetFromDoc( maLocationModel.maRange.aStart.Tab() ), UNO_QUERY_THROW ); + Reference< XDataPilotTables > xDPTables( xDPTablesSupp->getDataPilotTables(), UNO_SET_THROW ); + mxDPDescriptor.set( xDPTables->createDataPilotDescriptor(), UNO_SET_THROW ); + ScRange aRange = mpPivotCache->getSourceRange(); + CellRangeAddress aCellRangeAddress( aRange.aStart.Tab(), + aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aEnd.Col(), aRange.aEnd.Row() ); + mxDPDescriptor->setSourceRange( aCellRangeAddress ); + mxDPDescriptor->setTag( maDefModel.maTag ); + + // TODO: This is a hack. Eventually we need to convert the whole thing to the internal API. + auto pImpl = comphelper::getUnoTunnelImplementation<ScDataPilotDescriptorBase>(mxDPDescriptor); + if (!pImpl) + return; + + mpDPObject = pImpl->GetDPObject(); + if (!mpDPObject) + return; + + // global data pilot properties + PropertySet aDescProp( mxDPDescriptor ); + aDescProp.setProperty( PROP_ColumnGrand, maDefModel.mbColGrandTotals ); + aDescProp.setProperty( PROP_RowGrand, maDefModel.mbRowGrandTotals ); + aDescProp.setProperty( PROP_ShowFilterButton, false ); + aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill ); + + // finalize all fields, this finds field names and creates grouping fields + finalizeFieldsImport(); + + // all row fields + for( const auto& rRowField : maRowFields ) + if( PivotTableField* pField = getTableField( rRowField ) ) + pField->convertRowField(); + + // all column fields + for( const auto& rColField : maColFields ) + if( PivotTableField* pField = getTableField( rColField ) ) + pField->convertColField(); + + // all page fields + for( const auto& rPageField : maPageFields ) + if( PivotTableField* pField = getTableField( rPageField.mnField ) ) + pField->convertPageField( rPageField ); + + // all hidden fields + ::std::set< sal_Int32 > aVisFields; + aVisFields.insert( maRowFields.begin(), maRowFields.end() ); + aVisFields.insert( maColFields.begin(), maColFields.end() ); + for( const auto& rPageField : maPageFields ) + aVisFields.insert( rPageField.mnField ); + sal_Int32 nIndex = 0; + for( auto& rxField : maFields ) { - // clear destination area of the original pivot table - try - { - Reference< XSheetOperation > xSheetOp( getCellRangeFromDoc( maLocationModel.maRange ), UNO_QUERY_THROW ); - using namespace ::com::sun::star::sheet::CellFlags; - xSheetOp->clearContents( VALUE | DATETIME | STRING | FORMULA | HARDATTR | STYLES | EDITATTR | FORMATTED ); - } - catch( Exception& ) - { - } + if( aVisFields.count( nIndex ) == 0 ) + rxField->convertHiddenField(); + ++nIndex; + } - try + // all data fields + for( auto& rDataField : maDataFields ) + { + if( const PivotCacheField* pCacheField = getCacheField( rDataField.mnField ) ) { - // create a new data pilot descriptor based on the source data - Reference< XDataPilotTablesSupplier > xDPTablesSupp( getSheetFromDoc( maLocationModel.maRange.aStart.Tab() ), UNO_QUERY_THROW ); - Reference< XDataPilotTables > xDPTables( xDPTablesSupp->getDataPilotTables(), UNO_SET_THROW ); - mxDPDescriptor.set( xDPTables->createDataPilotDescriptor(), UNO_SET_THROW ); - ScRange aRange = mpPivotCache->getSourceRange(); - CellRangeAddress aCellRangeAddress( aRange.aStart.Tab(), - aRange.aStart.Col(), aRange.aStart.Row(), - aRange.aEnd.Col(), aRange.aEnd.Row() ); - mxDPDescriptor->setSourceRange( aCellRangeAddress ); - mxDPDescriptor->setTag( maDefModel.maTag ); - - // TODO: This is a hack. Eventually we need to convert the whole thing to the internal API. - auto pImpl = comphelper::getUnoTunnelImplementation<ScDataPilotDescriptorBase>(mxDPDescriptor); - if (!pImpl) - return; - - mpDPObject = pImpl->GetDPObject(); - if (!mpDPObject) - return; - - // global data pilot properties - PropertySet aDescProp( mxDPDescriptor ); - aDescProp.setProperty( PROP_ColumnGrand, maDefModel.mbColGrandTotals ); - aDescProp.setProperty( PROP_RowGrand, maDefModel.mbRowGrandTotals ); - aDescProp.setProperty( PROP_ShowFilterButton, false ); - aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill ); - - // finalize all fields, this finds field names and creates grouping fields - finalizeFieldsImport(); - - // all row fields - for( const auto& rRowField : maRowFields ) - if( PivotTableField* pField = getTableField( rRowField ) ) - pField->convertRowField(); - - // all column fields - for( const auto& rColField : maColFields ) - if( PivotTableField* pField = getTableField( rColField ) ) - pField->convertColField(); - - // all page fields - for( const auto& rPageField : maPageFields ) - if( PivotTableField* pField = getTableField( rPageField.mnField ) ) - pField->convertPageField( rPageField ); - - // all hidden fields - ::std::set< sal_Int32 > aVisFields; - aVisFields.insert( maRowFields.begin(), maRowFields.end() ); - aVisFields.insert( maColFields.begin(), maColFields.end() ); - for( const auto& rPageField : maPageFields ) - aVisFields.insert( rPageField.mnField ); - sal_Int32 nIndex = 0; - for( auto& rxField : maFields ) - { - if( aVisFields.count( nIndex ) == 0 ) - rxField->convertHiddenField(); - ++nIndex; - } - - // all data fields - for( auto& rDataField : maDataFields ) - { - if( const PivotCacheField* pCacheField = getCacheField( rDataField.mnField ) ) - { - if ( pCacheField-> getGroupBaseField() != -1 ) - rDataField.mnField = pCacheField-> getGroupBaseField(); - } - if( PivotTableField* pField = getTableField( rDataField.mnField ) ) - pField->convertDataField( rDataField ); - } + if ( pCacheField-> getGroupBaseField() != -1 ) + rDataField.mnField = pCacheField-> getGroupBaseField(); + } + if( PivotTableField* pField = getTableField( rDataField.mnField ) ) + pField->convertDataField( rDataField ); + } - // filters - maFilters.forEachMem( &PivotTableFilter::finalizeImport ); + // filters + maFilters.forEachMem( &PivotTableFilter::finalizeImport ); - // calculate base position of table - CellAddress aPos( maLocationModel.maRange.aStart.Tab(), maLocationModel.maRange.aStart.Col(), maLocationModel.maRange.aStart.Row() ); - /* If page fields exist, include them into the destination - area (they are excluded in Excel). Add an extra blank row. */ - if( !maPageFields.empty() ) - aPos.Row = ::std::max< sal_Int32 >( static_cast< sal_Int32 >( aPos.Row - maPageFields.size() - 1 ), 0 ); + // calculate base position of table + CellAddress aPos( maLocationModel.maRange.aStart.Tab(), maLocationModel.maRange.aStart.Col(), maLocationModel.maRange.aStart.Row() ); + /* If page fields exist, include them into the destination + area (they are excluded in Excel). Add an extra blank row. */ + if( !maPageFields.empty() ) + aPos.Row = ::std::max< sal_Int32 >( static_cast< sal_Int32 >( aPos.Row - maPageFields.size() - 1 ), 0 ); - // save interop grab bag - mpDPObject->PutInteropGrabBag(std::move(maInteropGrabBag)); + // save interop grab bag + mpDPObject->PutInteropGrabBag(std::move(maInteropGrabBag)); - // insert the DataPilot table into the sheet - xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor ); - } - catch( Exception& ) - { - OSL_FAIL( "PivotTable::finalizeImport - exception while creating the DataPilot table" ); - } - } + // insert the DataPilot table into the sheet + xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor ); + } + catch( Exception& ) + { + OSL_FAIL( "PivotTable::finalizeImport - exception while creating the DataPilot table" ); } } diff --git a/sc/source/filter/oox/querytablebuffer.cxx b/sc/source/filter/oox/querytablebuffer.cxx index 268d7a929629..fc1110406dd8 100644 --- a/sc/source/filter/oox/querytablebuffer.cxx +++ b/sc/source/filter/oox/querytablebuffer.cxx @@ -214,52 +214,52 @@ void QueryTable::finalizeImport() { ConnectionRef xConnection = getConnections().getConnection( maModel.mnConnId ); OSL_ENSURE( xConnection, "QueryTable::finalizeImport - missing connection object" ); - if( xConnection && (xConnection->getConnectionType() == BIFF12_CONNECTION_HTML) ) + if( !(xConnection && (xConnection->getConnectionType() == BIFF12_CONNECTION_HTML)) ) + return; + + // check that valid web query properties exist + const WebPrModel* pWebPr = xConnection->getModel().mxWebPr.get(); + if( !(pWebPr && !pWebPr->mbXml) ) + return; + + OUString aFileUrl = getBaseFilter().getAbsoluteUrl( pWebPr->maUrl ); + if( aFileUrl.isEmpty() ) + return; + + // resolve destination cell range (stored as defined name containing the range) + OUString aDefName = maModel.maDefName.replace( ' ', '_' ).replace( '-', '_' ); + DefinedNameRef xDefName = getDefinedNames().getByModelName( aDefName, getSheetIndex() ); + OSL_ENSURE( xDefName, "QueryTable::finalizeImport - missing defined name" ); + if( !xDefName ) + return; + + ScRange aDestRange; + bool bIsRange = xDefName->getAbsoluteRange( aDestRange ) && (aDestRange.aStart.Tab() == getSheetIndex()); + OSL_ENSURE( bIsRange, "QueryTable::finalizeImport - defined name does not contain valid cell range" ); + if( !(bIsRange && getAddressConverter().checkCellRange( aDestRange, false, true )) ) + return; + + // find tables mode: entire document, all tables, or specific tables + OUString aTables = pWebPr->mbHtmlTables ? lclBuildWebQueryTables( pWebPr->maTables ) : "HTML_all"; + if( !aTables.isEmpty() ) try { - // check that valid web query properties exist - const WebPrModel* pWebPr = xConnection->getModel().mxWebPr.get(); - if( pWebPr && !pWebPr->mbXml ) + PropertySet aDocProps( getDocument() ); + Reference< XAreaLinks > xAreaLinks( aDocProps.getAnyProperty( PROP_AreaLinks ), UNO_QUERY_THROW ); + CellAddress aDestPos( aDestRange.aStart.Tab(), aDestRange.aStart.Col(), aDestRange.aStart.Row() ); + OUString aFilterName = "calc_HTML_WebQuery"; + OUString aFilterOptions; + xAreaLinks->insertAtPosition( aDestPos, aFileUrl, aTables, aFilterName, aFilterOptions ); + // set refresh interval (convert minutes to seconds) + sal_Int32 nRefreshPeriod = xConnection->getModel().mnInterval * 60; + if( nRefreshPeriod > 0 ) { - OUString aFileUrl = getBaseFilter().getAbsoluteUrl( pWebPr->maUrl ); - if( !aFileUrl.isEmpty() ) - { - // resolve destination cell range (stored as defined name containing the range) - OUString aDefName = maModel.maDefName.replace( ' ', '_' ).replace( '-', '_' ); - DefinedNameRef xDefName = getDefinedNames().getByModelName( aDefName, getSheetIndex() ); - OSL_ENSURE( xDefName, "QueryTable::finalizeImport - missing defined name" ); - if( xDefName ) - { - ScRange aDestRange; - bool bIsRange = xDefName->getAbsoluteRange( aDestRange ) && (aDestRange.aStart.Tab() == getSheetIndex()); - OSL_ENSURE( bIsRange, "QueryTable::finalizeImport - defined name does not contain valid cell range" ); - if( bIsRange && getAddressConverter().checkCellRange( aDestRange, false, true ) ) - { - // find tables mode: entire document, all tables, or specific tables - OUString aTables = pWebPr->mbHtmlTables ? lclBuildWebQueryTables( pWebPr->maTables ) : "HTML_all"; - if( !aTables.isEmpty() ) try - { - PropertySet aDocProps( getDocument() ); - Reference< XAreaLinks > xAreaLinks( aDocProps.getAnyProperty( PROP_AreaLinks ), UNO_QUERY_THROW ); - CellAddress aDestPos( aDestRange.aStart.Tab(), aDestRange.aStart.Col(), aDestRange.aStart.Row() ); - OUString aFilterName = "calc_HTML_WebQuery"; - OUString aFilterOptions; - xAreaLinks->insertAtPosition( aDestPos, aFileUrl, aTables, aFilterName, aFilterOptions ); - // set refresh interval (convert minutes to seconds) - sal_Int32 nRefreshPeriod = xConnection->getModel().mnInterval * 60; - if( nRefreshPeriod > 0 ) - { - PropertySet aPropSet( lclFindAreaLink( xAreaLinks, aDestRange.aStart, aFileUrl, aTables, aFilterName, aFilterOptions ) ); - aPropSet.setProperty( PROP_RefreshPeriod, nRefreshPeriod ); - } - } - catch( Exception& ) - { - } - } - } - } + PropertySet aPropSet( lclFindAreaLink( xAreaLinks, aDestRange.aStart, aFileUrl, aTables, aFilterName, aFilterOptions ) ); + aPropSet.setProperty( PROP_RefreshPeriod, nRefreshPeriod ); } } + catch( Exception& ) + { + } } QueryTableBuffer::QueryTableBuffer( const WorksheetHelper& rHelper ) : diff --git a/sc/source/filter/oox/richstring.cxx b/sc/source/filter/oox/richstring.cxx index c2ea6afe3120..a9d058f75ba5 100644 --- a/sc/source/filter/oox/richstring.cxx +++ b/sc/source/filter/oox/richstring.cxx @@ -432,25 +432,25 @@ RichStringPhoneticRef RichString::createPhonetic() void RichString::createTextPortions( const OUString& rText, FontPortionModelList& rPortions ) { maTextPortions.clear(); - if( !rText.isEmpty() ) + if( rText.isEmpty() ) + return; + + sal_Int32 nStrLen = rText.getLength(); + // add leading and trailing string position to ease the following loop + if( rPortions.empty() || (rPortions.front().mnPos > 0) ) + rPortions.insert( rPortions.begin(), FontPortionModel( 0 ) ); + if( rPortions.back().mnPos < nStrLen ) + rPortions.push_back( FontPortionModel( nStrLen ) ); + + // create all string portions according to the font id vector + for( ::std::vector< FontPortionModel >::const_iterator aIt = rPortions.begin(); aIt->mnPos < nStrLen; ++aIt ) { - sal_Int32 nStrLen = rText.getLength(); - // add leading and trailing string position to ease the following loop - if( rPortions.empty() || (rPortions.front().mnPos > 0) ) - rPortions.insert( rPortions.begin(), FontPortionModel( 0 ) ); - if( rPortions.back().mnPos < nStrLen ) - rPortions.push_back( FontPortionModel( nStrLen ) ); - - // create all string portions according to the font id vector - for( ::std::vector< FontPortionModel >::const_iterator aIt = rPortions.begin(); aIt->mnPos < nStrLen; ++aIt ) + sal_Int32 nPortionLen = (aIt + 1)->mnPos - aIt->mnPos; + if( (0 < nPortionLen) && (aIt->mnPos + nPortionLen <= nStrLen) ) { - sal_Int32 nPortionLen = (aIt + 1)->mnPos - aIt->mnPos; - if( (0 < nPortionLen) && (aIt->mnPos + nPortionLen <= nStrLen) ) - { - RichStringPortionRef xPortion = createPortion(); - xPortion->setText( rText.copy( aIt->mnPos, nPortionLen ) ); - xPortion->setFontId( aIt->mnFontId ); - } + RichStringPortionRef xPortion = createPortion(); + xPortion->setText( rText.copy( aIt->mnPos, nPortionLen ) ); + xPortion->setFontId( aIt->mnFontId ); } } } @@ -458,26 +458,26 @@ void RichString::createTextPortions( const OUString& rText, FontPortionModelList void RichString::createPhoneticPortions( const OUString& rText, PhoneticPortionModelList& rPortions, sal_Int32 nBaseLen ) { maPhonPortions.clear(); - if( !rText.isEmpty()) + if( rText.isEmpty()) + return; + + sal_Int32 nStrLen = rText.getLength(); + // no portions - assign phonetic text to entire base text + if( rPortions.empty() ) + rPortions.push_back( PhoneticPortionModel( 0, 0, nBaseLen ) ); + // add trailing string position to ease the following loop + if( rPortions.back().mnPos < nStrLen ) + rPortions.push_back( PhoneticPortionModel( nStrLen, nBaseLen, 0 ) ); + + // create all phonetic portions according to the portions vector + for( ::std::vector< PhoneticPortionModel >::const_iterator aIt = rPortions.begin(); aIt->mnPos < nStrLen; ++aIt ) { - sal_Int32 nStrLen = rText.getLength(); - // no portions - assign phonetic text to entire base text - if( rPortions.empty() ) - rPortions.push_back( PhoneticPortionModel( 0, 0, nBaseLen ) ); - // add trailing string position to ease the following loop - if( rPortions.back().mnPos < nStrLen ) - rPortions.push_back( PhoneticPortionModel( nStrLen, nBaseLen, 0 ) ); - - // create all phonetic portions according to the portions vector - for( ::std::vector< PhoneticPortionModel >::const_iterator aIt = rPortions.begin(); aIt->mnPos < nStrLen; ++aIt ) + sal_Int32 nPortionLen = (aIt + 1)->mnPos - aIt->mnPos; + if( (0 < nPortionLen) && (aIt->mnPos + nPortionLen <= nStrLen) ) { - sal_Int32 nPortionLen = (aIt + 1)->mnPos - aIt->mnPos; - if( (0 < nPortionLen) && (aIt->mnPos + nPortionLen <= nStrLen) ) - { - RichStringPhoneticRef xPhonetic = createPhonetic(); - xPhonetic->setText( rText.copy( aIt->mnPos, nPortionLen ) ); - xPhonetic->setBaseRange( aIt->mnBasePos, aIt->mnBasePos + aIt->mnBaseLen ); - } + RichStringPhoneticRef xPhonetic = createPhonetic(); + xPhonetic->setText( rText.copy( aIt->mnPos, nPortionLen ) ); + xPhonetic->setBaseRange( aIt->mnBasePos, aIt->mnBasePos + aIt->mnBaseLen ); } } } diff --git a/sc/source/filter/oox/scenariobuffer.cxx b/sc/source/filter/oox/scenariobuffer.cxx index e52423ce6e01..7c45c822da27 100644 --- a/sc/source/filter/oox/scenariobuffer.cxx +++ b/sc/source/filter/oox/scenariobuffer.cxx @@ -109,7 +109,10 @@ void Scenario::finalizeImport() if( !rCell.mbDeleted && rAddrConv.checkCellAddress( rCell.maPos, true ) ) aRanges.push_back( ScRange(rCell.maPos, rCell.maPos) ); - if( !aRanges.empty() && !maModel.maName.isEmpty() ) try + if( aRanges.empty() || maModel.maName.isEmpty() ) + return; + + try { /* Find an unused name for the scenario (Calc stores scenario data in hidden sheets named after the scenario following the base sheet). */ diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx index fd4b760c41be..de1d2c76f3c9 100644 --- a/sc/source/filter/oox/sheetdatabuffer.cxx +++ b/sc/source/filter/oox/sheetdatabuffer.cxx @@ -325,25 +325,25 @@ typedef std::pair<sal_Int32, sal_Int32> FormatKeyPair; static void addIfNotInMyMap( const StylesBuffer& rStyles, std::map< FormatKeyPair, ScRangeList >& rMap, sal_Int32 nXfId, sal_Int32 nFormatId, const ScRangeList& rRangeList ) { Xf* pXf1 = rStyles.getCellXf( nXfId ).get(); - if ( pXf1 ) + if ( !pXf1 ) + return; + + auto it = std::find_if(rMap.begin(), rMap.end(), + [&nFormatId, &rStyles, &pXf1](const std::pair<FormatKeyPair, ScRangeList>& rEntry) { + if (rEntry.first.second != nFormatId) + return false; + Xf* pXf2 = rStyles.getCellXf( rEntry.first.first ).get(); + return *pXf1 == *pXf2; + }); + if (it != rMap.end()) // already exists { - auto it = std::find_if(rMap.begin(), rMap.end(), - [&nFormatId, &rStyles, &pXf1](const std::pair<FormatKeyPair, ScRangeList>& rEntry) { - if (rEntry.first.second != nFormatId) - return false; - Xf* pXf2 = rStyles.getCellXf( rEntry.first.first ).get(); - return *pXf1 == *pXf2; - }); - if (it != rMap.end()) // already exists - { - // add ranges from the rangelist to the existing rangelist for the - // matching style ( should we check if they overlap ? ) - for (size_t i = 0, nSize = rRangeList.size(); i < nSize; ++i) - it->second.push_back(rRangeList[i]); - return; - } - rMap[ FormatKeyPair( nXfId, nFormatId ) ] = rRangeList; + // add ranges from the rangelist to the existing rangelist for the + // matching style ( should we check if they overlap ? ) + for (size_t i = 0, nSize = rRangeList.size(); i < nSize; ++i) + it->second.push_back(rRangeList[i]); + return; } + rMap[ FormatKeyPair( nXfId, nFormatId ) ] = rRangeList; } void SheetDataBuffer::addColXfStyle( sal_Int32 nXfId, sal_Int32 nFormatId, const ScRange& rAddress, bool bProcessRowRange ) @@ -657,66 +657,67 @@ void SheetDataBuffer::finalizeTableOperation( const ScRange& rRange, const DataT void SheetDataBuffer::setCellFormat( const CellModel& rModel ) { - if( rModel.mnXfId >= 0 ) + if( rModel.mnXfId < 0 ) + return; + + ScRangeList& rRangeList = maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, -1 ) ]; + ScRange* pLastRange = rRangeList.empty() ? nullptr : &rRangeList.back(); + /* The xlsx sheet data contains row wise information. + * It is sufficient to check if the row range size is one + */ + if (!rRangeList.empty() && + *pLastRange == rModel.maCellAddr) + ; // do nothing - this probably bad data + else if (!rRangeList.empty() && + pLastRange->aStart.Tab() == rModel.maCellAddr.Tab() && + pLastRange->aStart.Row() == pLastRange->aEnd.Row() && + pLastRange->aStart.Row() == rModel.maCellAddr.Row() && + pLastRange->aEnd.Col() + 1 == rModel.maCellAddr.Col()) { - ScRangeList& rRangeList = maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, -1 ) ]; - ScRange* pLastRange = rRangeList.empty() ? nullptr : &rRangeList.back(); - /* The xlsx sheet data contains row wise information. - * It is sufficient to check if the row range size is one - */ - if (!rRangeList.empty() && - *pLastRange == rModel.maCellAddr) - ; // do nothing - this probably bad data - else if (!rRangeList.empty() && - pLastRange->aStart.Tab() == rModel.maCellAddr.Tab() && - pLastRange->aStart.Row() == pLastRange->aEnd.Row() && - pLastRange->aStart.Row() == rModel.maCellAddr.Row() && - pLastRange->aEnd.Col() + 1 == rModel.maCellAddr.Col()) - { - pLastRange->aEnd.IncCol(); // Expand Column - } - else - { - rRangeList.push_back(ScRange(rModel.maCellAddr)); - pLastRange = &rRangeList.back(); - } + pLastRange->aEnd.IncCol(); // Expand Column + } + else + { + rRangeList.push_back(ScRange(rModel.maCellAddr)); + pLastRange = &rRangeList.back(); + } - if (rRangeList.size() > 1) + if (rRangeList.size() > 1) + { + for (size_t i = rRangeList.size() - 1; i != 0; --i) { - for (size_t i = rRangeList.size() - 1; i != 0; --i) - { - ScRange& rMergeRange = rRangeList[i - 1]; - if (pLastRange->aStart.Tab() != rMergeRange.aStart.Tab()) - break; + ScRange& rMergeRange = rRangeList[i - 1]; + if (pLastRange->aStart.Tab() != rMergeRange.aStart.Tab()) + break; - /* Try to merge this with the previous range */ - if (pLastRange->aStart.Row() == (rMergeRange.aEnd.Row() + 1) && - pLastRange->aStart.Col() == rMergeRange.aStart.Col() && - pLastRange->aEnd.Col() == rMergeRange.aEnd.Col()) - { - rMergeRange.aEnd.SetRow(pLastRange->aEnd.Row()); - rRangeList.Remove(rRangeList.size() - 1); - break; - } - else if (pLastRange->aStart.Row() > (rMergeRange.aEnd.Row() + 1)) - break; // Un-necessary to check with any other rows - } - } - // update merged ranges for 'center across selection' and 'fill' - if( const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get() ) - { - sal_Int32 nHorAlign = pXf->getAlignment().getModel().mnHorAlign; - if( (nHorAlign == XML_centerContinuous) || (nHorAlign == XML_fill) ) + /* Try to merge this with the previous range */ + if (pLastRange->aStart.Row() == (rMergeRange.aEnd.Row() + 1) && + pLastRange->aStart.Col() == rMergeRange.aStart.Col() && + pLastRange->aEnd.Col() == rMergeRange.aEnd.Col()) { - /* start new merged range, if cell is not empty (#108781#), - or try to expand last range with empty cell */ - if( rModel.mnCellType != XML_TOKEN_INVALID ) - maCenterFillRanges.emplace_back( rModel.maCellAddr, nHorAlign ); - else if( !maCenterFillRanges.empty() ) - maCenterFillRanges.rbegin()->tryExpand( rModel.maCellAddr, nHorAlign ); + rMergeRange.aEnd.SetRow(pLastRange->aEnd.Row()); + rRangeList.Remove(rRangeList.size() - 1); + break; } + else if (pLastRange->aStart.Row() > (rMergeRange.aEnd.Row() + 1)) + break; // Un-necessary to check with any other rows } } + // update merged ranges for 'center across selection' and 'fill' + const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get(); + if( !pXf ) + return; + + sal_Int32 nHorAlign = pXf->getAlignment().getModel().mnHorAlign; + if( (nHorAlign == XML_centerContinuous) || (nHorAlign == XML_fill) ) + { + /* start new merged range, if cell is not empty (#108781#), + or try to expand last range with empty cell */ + if( rModel.mnCellType != XML_TOKEN_INVALID ) + maCenterFillRanges.emplace_back( rModel.maCellAddr, nHorAlign ); + else if( !maCenterFillRanges.empty() ) + maCenterFillRanges.rbegin()->tryExpand( rModel.maCellAddr, nHorAlign ); + } } static void lcl_SetBorderLine( ScDocument& rDoc, const ScRange& rRange, SCTAB nScTab, SvxBoxItemLine nLine ) diff --git a/sc/source/filter/oox/sheetdatacontext.cxx b/sc/source/filter/oox/sheetdatacontext.cxx index 242192f67350..c2b47a130bf4 100644 --- a/sc/source/filter/oox/sheetdatacontext.cxx +++ b/sc/source/filter/oox/sheetdatacontext.cxx @@ -122,92 +122,92 @@ void SheetDataContext::onCharacters( const OUString& rChars ) void SheetDataContext::onEndElement() { - if( getCurrentElement() == XLS_TOKEN( c ) ) - { - // try to create a formula cell - if( mbHasFormula ) switch( maFmlaData.mnFormulaType ) - { - // will buffer formulas but need to - // a) need to set format first - // :/ - case XML_normal: - setCellFormula( maCellData.maCellAddr, maFormulaStr ); - mrSheetData.setCellFormat( maCellData ); + if( getCurrentElement() != XLS_TOKEN( c ) ) + return; - // If a number cell has some preloaded value, stick it into the buffer - // but do this only for real cell formulas (not array, shared etc.) - if (!maCellValue.isEmpty()) - setCellFormulaValue(maCellData.maCellAddr, maCellValue, maCellData.mnCellType); - break; - - case XML_shared: - if( maFmlaData.mnSharedId >= 0 ) - { - if( mbValidRange && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) ) - createSharedFormulaMapEntry(maCellData.maCellAddr, maFmlaData.mnSharedId, maFormulaStr); - - setCellFormula(maCellData.maCellAddr, maFmlaData.mnSharedId, maCellValue, maCellData.mnCellType); - mrSheetData.setCellFormat( maCellData ); - } - else - // no success, set plain cell value and formatting below - mbHasFormula = false; - break; - case XML_array: - if( mbValidRange && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) ) - { - setCellArrayFormula( maFmlaData.maFormulaRef, maCellData.maCellAddr, maFormulaStr ); - } - // set cell formatting, but do not set result as cell value - mrSheetData.setBlankCell( maCellData ); - break; - case XML_dataTable: - if( mbValidRange ) - mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData ); - // set cell formatting, but do not set result as cell value - mrSheetData.setBlankCell( maCellData ); + // try to create a formula cell + if( mbHasFormula ) switch( maFmlaData.mnFormulaType ) + { + // will buffer formulas but need to + // a) need to set format first + // :/ + case XML_normal: + setCellFormula( maCellData.maCellAddr, maFormulaStr ); + mrSheetData.setCellFormat( maCellData ); + + // If a number cell has some preloaded value, stick it into the buffer + // but do this only for real cell formulas (not array, shared etc.) + if (!maCellValue.isEmpty()) + setCellFormulaValue(maCellData.maCellAddr, maCellValue, maCellData.mnCellType); break; - default: - OSL_ENSURE( maFmlaData.mnFormulaType == XML_TOKEN_INVALID, "SheetDataContext::onEndElement - unknown formula type" ); - mbHasFormula = false; - } - if( !mbHasFormula ) - { - // no formula created: try to set the cell value - if( !maCellValue.isEmpty() ) switch( maCellData.mnCellType ) + case XML_shared: + if( maFmlaData.mnSharedId >= 0 ) { - case XML_n: - mrSheetData.setValueCell( maCellData, maCellValue.toDouble() ); - break; - case XML_b: - mrSheetData.setBooleanCell( maCellData, maCellValue.toDouble() != 0.0 ); - break; - case XML_e: - mrSheetData.setErrorCell( maCellData, maCellValue ); - break; - case XML_str: - mrSheetData.setStringCell( maCellData, maCellValue ); - break; - case XML_s: - mrSheetData.setStringCell( maCellData, maCellValue.toInt32() ); - break; - case XML_d: - mrSheetData.setDateCell( maCellData, maCellValue ); - break; - } - else if( (maCellData.mnCellType == XML_inlineStr) && mxInlineStr ) - { - mxInlineStr->finalizeImport(); - mrSheetData.setStringCell( maCellData, mxInlineStr ); + if( mbValidRange && maFmlaData.isValidSharedRef( maCellData.maCellAddr ) ) + createSharedFormulaMapEntry(maCellData.maCellAddr, maFmlaData.mnSharedId, maFormulaStr); + + setCellFormula(maCellData.maCellAddr, maFmlaData.mnSharedId, maCellValue, maCellData.mnCellType); + mrSheetData.setCellFormat( maCellData ); } else + // no success, set plain cell value and formatting below + mbHasFormula = false; + break; + case XML_array: + if( mbValidRange && maFmlaData.isValidArrayRef( maCellData.maCellAddr ) ) { - // empty cell, update cell type - maCellData.mnCellType = XML_TOKEN_INVALID; - mrSheetData.setBlankCell( maCellData ); + setCellArrayFormula( maFmlaData.maFormulaRef, maCellData.maCellAddr, maFormulaStr ); } - } + // set cell formatting, but do not set result as cell value + mrSheetData.setBlankCell( maCellData ); + break; + case XML_dataTable: + if( mbValidRange ) + mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData ); + // set cell formatting, but do not set result as cell value + mrSheetData.setBlankCell( maCellData ); + break; + default: + OSL_ENSURE( maFmlaData.mnFormulaType == XML_TOKEN_INVALID, "SheetDataContext::onEndElement - unknown formula type" ); + mbHasFormula = false; + } + + if( mbHasFormula ) + return; + + // no formula created: try to set the cell value + if( !maCellValue.isEmpty() ) switch( maCellData.mnCellType ) + { + case XML_n: + mrSheetData.setValueCell( maCellData, maCellValue.toDouble() ); + break; + case XML_b: + mrSheetData.setBooleanCell( maCellData, maCellValue.toDouble() != 0.0 ); + break; + case XML_e: + mrSheetData.setErrorCell( maCellData, maCellValue ); + break; + case XML_str: + mrSheetData.setStringCell( maCellData, maCellValue ); + break; + case XML_s: + mrSheetData.setStringCell( maCellData, maCellValue.toInt32() ); + break; + case XML_d: + mrSheetData.setDateCell( maCellData, maCellValue ); + break; + } + else if( (maCellData.mnCellType == XML_inlineStr) && mxInlineStr ) + { + mxInlineStr->finalizeImport(); + mrSheetData.setStringCell( maCellData, mxInlineStr ); + } + else + { + // empty cell, update cell type + maCellData.mnCellType = XML_TOKEN_INVALID; + mrSheetData.setBlankCell( maCellData ); } } @@ -546,20 +546,20 @@ void SheetDataContext::importArray( SequenceInputStream& rStrm ) void SheetDataContext::importDataTable( SequenceInputStream& rStrm ) { - if( readFormulaRef( rStrm ) ) - { - BinAddress aRef1, aRef2; - sal_uInt8 nFlags; - rStrm >> aRef1 >> aRef2; - nFlags = rStrm.readuChar(); - maTableData.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false ); - maTableData.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false ); - maTableData.mbRowTable = getFlag( nFlags, BIFF12_DATATABLE_ROW ); - maTableData.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D ); - maTableData.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL ); - maTableData.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL ); - mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData ); - } + if( !readFormulaRef( rStrm ) ) + return; + + BinAddress aRef1, aRef2; + sal_uInt8 nFlags; + rStrm >> aRef1 >> aRef2; + nFlags = rStrm.readuChar(); + maTableData.maRef1 = FormulaProcessorBase::generateAddress2dString( aRef1, false ); + maTableData.maRef2 = FormulaProcessorBase::generateAddress2dString( aRef2, false ); + maTableData.mbRowTable = getFlag( nFlags, BIFF12_DATATABLE_ROW ); + maTableData.mb2dTable = getFlag( nFlags, BIFF12_DATATABLE_2D ); + maTableData.mbRef1Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF1DEL ); + maTableData.mbRef2Deleted = getFlag( nFlags, BIFF12_DATATABLE_REF2DEL ); + mrSheetData.createTableOperation( maFmlaData.maFormulaRef, maTableData ); } void SheetDataContext::importSharedFmla( SequenceInputStream& rStrm ) diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx index 3ec09651ac11..89bc91dc17e4 100644 --- a/sc/source/filter/oox/stylesbuffer.cxx +++ b/sc/source/filter/oox/stylesbuffer.cxx @@ -782,51 +782,51 @@ void Font::finalizeImport() } // supported script types - if( maUsedFlags.mbNameUsed ) - { - PropertySet aDocProps( getDocument() ); - Reference< XDevice > xDevice( aDocProps.getAnyProperty( PROP_ReferenceDevice ), UNO_QUERY ); - if( xDevice.is() ) - { - Reference< XFont2 > xFont( xDevice->getFont( maApiData.maDesc ), UNO_QUERY ); - if( xFont.is() ) - { - // #91658# CJK fonts - bool bHasAsian = - xFont->hasGlyphs( OUString( u'\x3041' ) ) || // 3040-309F: Hiragana - xFont->hasGlyphs( OUString( u'\x30A1' ) ) || // 30A0-30FF: Katakana - xFont->hasGlyphs( OUString( u'\x3111' ) ) || // 3100-312F: Bopomofo - xFont->hasGlyphs( OUString( u'\x3131' ) ) || // 3130-318F: Hangul Compatibility Jamo - xFont->hasGlyphs( OUString( u'\x3301' ) ) || // 3300-33FF: CJK Compatibility - xFont->hasGlyphs( OUString( u'\x3401' ) ) || // 3400-4DBF: CJK Unified Ideographs Extension A - xFont->hasGlyphs( OUString( u'\x4E01' ) ) || // 4E00-9FFF: CJK Unified Ideographs - xFont->hasGlyphs( OUString( u'\x7E01' ) ) || // 4E00-9FFF: CJK Unified Ideographs - xFont->hasGlyphs( OUString( u'\xA001' ) ) || // A001-A48F: Yi Syllables - xFont->hasGlyphs( OUString( u'\xAC01' ) ) || // AC00-D7AF: Hangul Syllables - xFont->hasGlyphs( OUString( u'\xCC01' ) ) || // AC00-D7AF: Hangul Syllables - xFont->hasGlyphs( OUString( u'\xF901' ) ) || // F900-FAFF: CJK Compatibility Ideographs - xFont->hasGlyphs( OUString( u'\xFF71' ) ); // FF00-FFEF: Halfwidth/Fullwidth Forms - // #113783# CTL fonts - bool bHasCmplx = - xFont->hasGlyphs( OUString( u'\x05D1' ) ) || // 0590-05FF: Hebrew - xFont->hasGlyphs( OUString( u'\x0631' ) ) || // 0600-06FF: Arabic - xFont->hasGlyphs( OUString( u'\x0721' ) ) || // 0700-074F: Syriac - xFont->hasGlyphs( OUString( u'\x0911' ) ) || // 0900-0DFF: Indic scripts - xFont->hasGlyphs( OUString( u'\x0E01' ) ) || // 0E00-0E7F: Thai - xFont->hasGlyphs( OUString( u'\xFB21' ) ) || // FB1D-FB4F: Hebrew Presentation Forms - xFont->hasGlyphs( OUString( u'\xFB51' ) ) || // FB50-FDFF: Arabic Presentation Forms-A - xFont->hasGlyphs( OUString( u'\xFE71' ) ); // FE70-FEFF: Arabic Presentation Forms-B - // Western fonts - bool bHasLatin = - (!bHasAsian && !bHasCmplx) || - xFont->hasGlyphs( OUString( 'A' ) ); - - lclSetFontName( maApiData.maLatinFont, maApiData.maDesc, bHasLatin ); - lclSetFontName( maApiData.maAsianFont, maApiData.maDesc, bHasAsian ); - lclSetFontName( maApiData.maCmplxFont, maApiData.maDesc, bHasCmplx ); - } - } - } + if( !maUsedFlags.mbNameUsed ) + return; + + PropertySet aDocProps( getDocument() ); + Reference< XDevice > xDevice( aDocProps.getAnyProperty( PROP_ReferenceDevice ), UNO_QUERY ); + if( !xDevice.is() ) + return; + + Reference< XFont2 > xFont( xDevice->getFont( maApiData.maDesc ), UNO_QUERY ); + if( !xFont.is() ) + return; + + // #91658# CJK fonts + bool bHasAsian = + xFont->hasGlyphs( OUString( u'\x3041' ) ) || // 3040-309F: Hiragana + xFont->hasGlyphs( OUString( u'\x30A1' ) ) || // 30A0-30FF: Katakana + xFont->hasGlyphs( OUString( u'\x3111' ) ) || // 3100-312F: Bopomofo + xFont->hasGlyphs( OUString( u'\x3131' ) ) || // 3130-318F: Hangul Compatibility Jamo + xFont->hasGlyphs( OUString( u'\x3301' ) ) || // 3300-33FF: CJK Compatibility + xFont->hasGlyphs( OUString( u'\x3401' ) ) || // 3400-4DBF: CJK Unified Ideographs Extension A + xFont->hasGlyphs( OUString( u'\x4E01' ) ) || // 4E00-9FFF: CJK Unified Ideographs + xFont->hasGlyphs( OUString( u'\x7E01' ) ) || // 4E00-9FFF: CJK Unified Ideographs + xFont->hasGlyphs( OUString( u'\xA001' ) ) || // A001-A48F: Yi Syllables + xFont->hasGlyphs( OUString( u'\xAC01' ) ) || // AC00-D7AF: Hangul Syllables + xFont->hasGlyphs( OUString( u'\xCC01' ) ) || // AC00-D7AF: Hangul Syllables + xFont->hasGlyphs( OUString( u'\xF901' ) ) || // F900-FAFF: CJK Compatibility Ideographs + xFont->hasGlyphs( OUString( u'\xFF71' ) ); // FF00-FFEF: Halfwidth/Fullwidth Forms + // #113783# CTL fonts + bool bHasCmplx = + xFont->hasGlyphs( OUString( u'\x05D1' ) ) || // 0590-05FF: Hebrew + xFont->hasGlyphs( OUString( u'\x0631' ) ) || // 0600-06FF: Arabic + xFont->hasGlyphs( OUString( u'\x0721' ) ) || // 0700-074F: Syriac + xFont->hasGlyphs( OUString( u'\x0911' ) ) || // 0900-0DFF: Indic scripts + xFont->hasGlyphs( OUString( u'\x0E01' ) ) || // 0E00-0E7F: Thai + xFont->hasGlyphs( OUString( u'\xFB21' ) ) || // FB1D-FB4F: Hebrew Presentation Forms + xFont->hasGlyphs( OUString( u'\xFB51' ) ) || // FB50-FDFF: Arabic Presentation Forms-A + xFont->hasGlyphs( OUString( u'\xFE71' ) ); // FE70-FEFF: Arabic Presentation Forms-B + // Western fonts + bool bHasLatin = + (!bHasAsian && !bHasCmplx) || + xFont->hasGlyphs( OUString( 'A' ) ); + + lclSetFontName( maApiData.maLatinFont, maApiData.maDesc, bHasLatin ); + lclSetFontName( maApiData.maAsianFont, maApiData.maDesc, bHasAsian ); + lclSetFontName( maApiData.maCmplxFont, maApiData.maDesc, bHasCmplx ); } bool Font::needsRichTextFormat() const @@ -961,18 +961,18 @@ void Font::fillToItemSet( SfxItemSet& rItemSet, bool bEditEngineText, bool bSkip { ScfTools::PutItem( rItemSet, SvxShadowedItem( maApiData.mbShadow, ATTR_FONT_SHADOWED ), bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_SHADOW) : ATTR_FONT_SHADOWED, bSkipPoolDefs ); } - if( maUsedFlags.mbEscapementUsed ) + if( !maUsedFlags.mbEscapementUsed ) + return; + + SvxEscapement eScEscapem = SvxEscapement::Off; + if ( maApiData.mnEscapement == API_ESCAPE_SUPERSCRIPT ) + eScEscapem = SvxEscapement::Superscript; + else if ( maApiData.mnEscapement == API_ESCAPE_SUBSCRIPT ) + eScEscapem = SvxEscapement::Subscript; + if( bEditEngineText ) { - SvxEscapement eScEscapem = SvxEscapement::Off; - if ( maApiData.mnEscapement == API_ESCAPE_SUPERSCRIPT ) - eScEscapem = SvxEscapement::Superscript; - else if ( maApiData.mnEscapement == API_ESCAPE_SUBSCRIPT ) - eScEscapem = SvxEscapement::Subscript; - if( bEditEngineText ) - { - // #TODO handle EscapementHeight - rItemSet.Put( SvxEscapementItem( eScEscapem, EE_CHAR_ESCAPEMENT ) ); - } + // #TODO handle EscapementHeight + rItemSet.Put( SvxEscapementItem( eScEscapem, EE_CHAR_ESCAPEMENT ) ); } } @@ -1523,22 +1523,22 @@ void Border::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const } ScfTools::PutItem( rItemSet, aBoxItem, bSkipPoolDefs ); } - if ( maApiData.mbDiagUsed ) + if ( !maApiData.mbDiagUsed ) + return; + + SvxLineItem aTLBRItem( ATTR_BORDER_TLBR ); + SvxLineItem aBLTRItem( ATTR_BORDER_BLTR ); + ::editeng::SvxBorderLine aLine; + if (SvxBoxItem::LineToSvxLine(maApiData.maTLtoBR, aLine, false)) { - SvxLineItem aTLBRItem( ATTR_BORDER_TLBR ); - SvxLineItem aBLTRItem( ATTR_BORDER_BLTR ); - ::editeng::SvxBorderLine aLine; - if (SvxBoxItem::LineToSvxLine(maApiData.maTLtoBR, aLine, false)) - { - aTLBRItem.SetLine( &aLine ); - } - if (SvxBoxItem::LineToSvxLine(maApiData.maBLtoTR, aLine, false)) - { - aBLTRItem.SetLine( &aLine ); - } - ScfTools::PutItem( rItemSet, aTLBRItem, bSkipPoolDefs ); - ScfTools::PutItem( rItemSet, aBLTRItem, bSkipPoolDefs ); + aTLBRItem.SetLine( &aLine ); } + if (SvxBoxItem::LineToSvxLine(maApiData.maBLtoTR, aLine, false)) + { + aBLTRItem.SetLine( &aLine ); + } + ScfTools::PutItem( rItemSet, aTLBRItem, bSkipPoolDefs ); + ScfTools::PutItem( rItemSet, aBLTRItem, bSkipPoolDefs ); } BorderLineModel* Border::getBorderLine( sal_Int32 nElement ) @@ -1901,19 +1901,19 @@ void Fill::finalizeImport() void Fill::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const { - if( maApiData.mbUsed ) + if( !maApiData.mbUsed ) + return; + + SvxBrushItem aBrushItem( ATTR_BACKGROUND ); + if ( maApiData.mbTransparent ) { - SvxBrushItem aBrushItem( ATTR_BACKGROUND ); - if ( maApiData.mbTransparent ) - { - aBrushItem.SetColor( COL_TRANSPARENT ); - } - else - { - aBrushItem.SetColor( maApiData.mnColor ); - } - ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs ); + aBrushItem.SetColor( COL_TRANSPARENT ); + } + else + { + aBrushItem.SetColor( maApiData.mnColor ); } + ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs ); } XfModel::XfModel() : @@ -2064,38 +2064,38 @@ void Xf::applyPatternToAttrList( AttrList& rAttrs, SCROW nRow1, SCROW nRow2, sal if (!sc::NumFmtUtil::isLatinScript(mnScNumFmt, rDoc)) rAttrs.mbLatinNumFmtOnly = false; - if (rPat.GetStyleName()) - { - // Check for a gap between the last entry and this one. - bool bHasGap = false; - if (rAttrs.maAttrs.empty() && nRow1 > 0) - // First attribute range doesn't start at row 0. - bHasGap = true; + if (!rPat.GetStyleName()) + return; - if (!rAttrs.maAttrs.empty() && rAttrs.maAttrs.back().nEndRow + 1 < nRow1) - bHasGap = true; + // Check for a gap between the last entry and this one. + bool bHasGap = false; + if (rAttrs.maAttrs.empty() && nRow1 > 0) + // First attribute range doesn't start at row 0. + bHasGap = true; - if (bHasGap) - { - // Fill this gap with the default pattern. - ScAttrEntry aEntry; - aEntry.nEndRow = nRow1 - 1; - aEntry.pPattern = &rDoc.GetPool()->Put(*rAttrs.mpDefPattern); - rAttrs.maAttrs.push_back(aEntry); - - // Check if the default pattern is 'General'. - if (!sc::NumFmtUtil::isLatinScript(*aEntry.pPattern, rDoc)) - rAttrs.mbLatinNumFmtOnly = false; - } + if (!rAttrs.maAttrs.empty() && rAttrs.maAttrs.back().nEndRow + 1 < nRow1) + bHasGap = true; + if (bHasGap) + { + // Fill this gap with the default pattern. ScAttrEntry aEntry; - aEntry.nEndRow = nRow2; - aEntry.pPattern = &rDoc.GetPool()->Put(rPat); + aEntry.nEndRow = nRow1 - 1; + aEntry.pPattern = &rDoc.GetPool()->Put(*rAttrs.mpDefPattern); rAttrs.maAttrs.push_back(aEntry); + // Check if the default pattern is 'General'. if (!sc::NumFmtUtil::isLatinScript(*aEntry.pPattern, rDoc)) rAttrs.mbLatinNumFmtOnly = false; } + + ScAttrEntry aEntry; + aEntry.nEndRow = nRow2; + aEntry.pPattern = &rDoc.GetPool()->Put(rPat); + rAttrs.maAttrs.push_back(aEntry); + + if (!sc::NumFmtUtil::isLatinScript(*aEntry.pPattern, rDoc)) + rAttrs.mbLatinNumFmtOnly = false; } void Xf::writeToDoc( ScDocumentImport& rDoc, const ScRange& rRange ) @@ -2485,34 +2485,34 @@ void CellStyle::createCellStyle() mbCreated = maFinalName.isEmpty(); } - if( !mbCreated && !mpStyleSheet ) - { - bool bCreatePattern = false; - Xf* pXF = getStyles().getStyleXf( maModel.mnXfId ).get(); - ::ScDocument& rDoc = getScDocument(); + if( mbCreated || mpStyleSheet ) + return; + + bool bCreatePattern = false; + Xf* pXF = getStyles().getStyleXf( maModel.mnXfId ).get(); + ::ScDocument& rDoc = getScDocument(); - if( bDefStyle ) + if( bDefStyle ) + { + // use existing "Default" style sheet + mpStyleSheet = static_cast< ScStyleSheet* >( rDoc.GetStyleSheetPool()->Find( + ScResId( STR_STYLENAME_STANDARD_CELL ), SfxStyleFamily::Para ) ); + OSL_ENSURE( mpStyleSheet, "CellStyle::createStyle - Default style not found" ); + bCreatePattern = true; + } + else + { + mpStyleSheet = static_cast< ScStyleSheet* >( rDoc.GetStyleSheetPool()->Find( maFinalName, SfxStyleFamily::Para ) ); + if( !mpStyleSheet ) { - // use existing "Default" style sheet - mpStyleSheet = static_cast< ScStyleSheet* >( rDoc.GetStyleSheetPool()->Find( - ScResId( STR_STYLENAME_STANDARD_CELL ), SfxStyleFamily::Para ) ); - OSL_ENSURE( mpStyleSheet, "CellStyle::createStyle - Default style not found" ); + mpStyleSheet = &static_cast< ScStyleSheet& >( rDoc.GetStyleSheetPool()->Make( maFinalName, SfxStyleFamily::Para, SfxStyleSearchBits::UserDefined ) ); bCreatePattern = true; } - else - { - mpStyleSheet = static_cast< ScStyleSheet* >( rDoc.GetStyleSheetPool()->Find( maFinalName, SfxStyleFamily::Para ) ); - if( !mpStyleSheet ) - { - mpStyleSheet = &static_cast< ScStyleSheet& >( rDoc.GetStyleSheetPool()->Make( maFinalName, SfxStyleFamily::Para, SfxStyleSearchBits::UserDefined ) ); - bCreatePattern = true; - } - } - - // bDefStyle==true omits default pool items in CreatePattern() - if( bCreatePattern && mpStyleSheet && pXF ) - mpStyleSheet->GetItemSet().Put( pXF->createPattern( bDefStyle ).GetItemSet() ); } + + // bDefStyle==true omits default pool items in CreatePattern() + if( bCreatePattern && mpStyleSheet && pXF ) + mpStyleSheet->GetItemSet().Put( pXF->createPattern( bDefStyle ).GetItemSet() ); } void CellStyle::finalizeImport( const OUString& rFinalName ) @@ -2646,19 +2646,19 @@ OUString CellStyleBuffer::createCellStyle( sal_Int32 nXfId ) const void CellStyleBuffer::insertCellStyle( CellStyleRef const & xCellStyle ) { const CellStyleModel& rModel = xCellStyle->getModel(); - if( rModel.mnXfId >= 0 ) - { - // insert into the built-in map or user defined map - (rModel.isBuiltin() ? maBuiltinStyles : maUserStyles).push_back( xCellStyle ); + if( rModel.mnXfId < 0 ) + return; - // insert into the XF identifier map - OSL_ENSURE( maStylesByXf.count( rModel.mnXfId ) == 0, "CellStyleBuffer::insertCellStyle - multiple styles with equal XF identifier" ); - maStylesByXf[ rModel.mnXfId ] = xCellStyle; + // insert into the built-in map or user defined map + (rModel.isBuiltin() ? maBuiltinStyles : maUserStyles).push_back( xCellStyle ); - // remember default cell style - if( rModel.isDefaultStyle() ) - mxDefStyle = xCellStyle; - } + // insert into the XF identifier map + OSL_ENSURE( maStylesByXf.count( rModel.mnXfId ) == 0, "CellStyleBuffer::insertCellStyle - multiple styles with equal XF identifier" ); + maStylesByXf[ rModel.mnXfId ] = xCellStyle; + + // remember default cell style + if( rModel.isDefaultStyle() ) + mxDefStyle = xCellStyle; } ::ScStyleSheet* CellStyleBuffer::getCellStyleSheet( const CellStyleRef& rxCellStyle ) diff --git a/sc/source/filter/oox/tablebuffer.cxx b/sc/source/filter/oox/tablebuffer.cxx index b0cf1b879409..6e46f0a257ab 100644 --- a/sc/source/filter/oox/tablebuffer.cxx +++ b/sc/source/filter/oox/tablebuffer.cxx @@ -88,7 +88,10 @@ void Table::finalizeImport() // ranges (or tables in their terminology) as Table1, Table2 etc. We need // to import them as named db ranges because they may be referenced by // name in formula expressions. - if( (maModel.mnId > 0) && !maModel.maDisplayName.isEmpty() ) try + if( (maModel.mnId <= 0) || maModel.maDisplayName.isEmpty() ) + return; + + try { maDBRangeName = maModel.maDisplayName; @@ -128,20 +131,20 @@ void Table::finalizeImport() void Table::applyAutoFilters() { - if( !maDBRangeName.isEmpty() ) + if( maDBRangeName.isEmpty() ) + return; + + try { - try - { - // get the range ( maybe we should cache the xDatabaseRange from finalizeImport ) - PropertySet aDocProps( getDocument() ); - Reference< XDatabaseRanges > xDatabaseRanges( aDocProps.getAnyProperty( PROP_DatabaseRanges ), UNO_QUERY_THROW ); - Reference< XDatabaseRange > xDatabaseRange( xDatabaseRanges->getByName( maDBRangeName ), UNO_QUERY ); - maAutoFilters.finalizeImport( xDatabaseRange ); - } - catch( Exception& ) - { - OSL_FAIL( "Table::applyAutofilters - cannot create filter" ); - } + // get the range ( maybe we should cache the xDatabaseRange from finalizeImport ) + PropertySet aDocProps( getDocument() ); + Reference< XDatabaseRanges > xDatabaseRanges( aDocProps.getAnyProperty( PROP_DatabaseRanges ), UNO_QUERY_THROW ); + Reference< XDatabaseRange > xDatabaseRange( xDatabaseRanges->getByName( maDBRangeName ), UNO_QUERY ); + maAutoFilters.finalizeImport( xDatabaseRange ); + } + catch( Exception& ) + { + OSL_FAIL( "Table::applyAutofilters - cannot create filter" ); } } diff --git a/sc/source/filter/oox/unitconverter.cxx b/sc/source/filter/oox/unitconverter.cxx index ce379a2bc426..088121286d9e 100644 --- a/sc/source/filter/oox/unitconverter.cxx +++ b/sc/source/filter/oox/unitconverter.cxx @@ -118,29 +118,30 @@ void UnitConverter::finalizeImport() { PropertySet aDocProps( getDocument() ); Reference< XDevice > xDevice( aDocProps.getAnyProperty( PROP_ReferenceDevice ), UNO_QUERY ); - if( xDevice.is() ) - { - // get character widths from default font - if( const oox::xls::Font* pDefFont = getStyles().getDefaultFont().get() ) - { - // XDevice expects pixels in font descriptor, but font contains twips - const FontDescriptor& aDesc = pDefFont->getFontDescriptor(); - Reference< XFont > xFont = xDevice->getFont( aDesc ); - if( xFont.is() ) - { - // get maximum width of all digits - sal_Int32 nDigitWidth = 0; - for( sal_Unicode cChar = '0'; cChar <= '9'; ++cChar ) - nDigitWidth = ::std::max( nDigitWidth, scaleToMm100( xFont->getCharWidth( cChar ), Unit::Twip ) ); - if( nDigitWidth > 0 ) - maCoeffs[ Unit::Digit ] = nDigitWidth; - // get width of space character - sal_Int32 nSpaceWidth = scaleToMm100( xFont->getCharWidth( ' ' ), Unit::Twip ); - if( nSpaceWidth > 0 ) - maCoeffs[ Unit::Space ] = nSpaceWidth; - } - } - } + if( !xDevice.is() ) + return; + + // get character widths from default font + const oox::xls::Font* pDefFont = getStyles().getDefaultFont().get(); + if( !pDefFont ) + return; + + // XDevice expects pixels in font descriptor, but font contains twips + const FontDescriptor& aDesc = pDefFont->getFontDescriptor(); + Reference< XFont > xFont = xDevice->getFont( aDesc ); + if( !xFont.is() ) + return; + + // get maximum width of all digits + sal_Int32 nDigitWidth = 0; + for( sal_Unicode cChar = '0'; cChar <= '9'; ++cChar ) + nDigitWidth = ::std::max( nDigitWidth, scaleToMm100( xFont->getCharWidth( cChar ), Unit::Twip ) ); + if( nDigitWidth > 0 ) + maCoeffs[ Unit::Digit ] = nDigitWidth; + // get width of space character + sal_Int32 nSpaceWidth = scaleToMm100( xFont->getCharWidth( ' ' ), Unit::Twip ); + if( nSpaceWidth > 0 ) + maCoeffs[ Unit::Space ] = nSpaceWidth; } void UnitConverter::finalizeNullDate( const util::Date& rNullDate ) diff --git a/sc/source/filter/oox/viewsettings.cxx b/sc/source/filter/oox/viewsettings.cxx index 215c7ce71f1e..64f20e23a07a 100644 --- a/sc/source/filter/oox/viewsettings.cxx +++ b/sc/source/filter/oox/viewsettings.cxx @@ -271,44 +271,44 @@ void SheetViewSettings::importSheetView( SequenceInputStream& rStrm ) void SheetViewSettings::importPane( SequenceInputStream& rStrm ) { OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importPane - missing sheet view model" ); - if( !maSheetViews.empty() ) - { - SheetViewModel& rModel = *maSheetViews.back(); + if( maSheetViews.empty() ) + return; - BinAddress aSecondPos; - sal_Int32 nActivePaneId; - sal_uInt8 nFlags; - rModel.mfSplitX = rStrm.readDouble(); - rModel.mfSplitY = rStrm.readDouble(); - rStrm >> aSecondPos; - nActivePaneId = rStrm.readInt32(); - nFlags = rStrm.readuChar(); - - rModel.maSecondPos = getAddressConverter().createValidCellAddress( aSecondPos, getSheetIndex(), false ); - rModel.mnActivePaneId = lclGetOoxPaneId( nActivePaneId, XML_topLeft ); - rModel.mnPaneState = getFlagValue( nFlags, BIFF12_PANE_FROZEN, getFlagValue( nFlags, BIFF12_PANE_FROZENNOSPLIT, XML_frozen, XML_frozenSplit ), XML_split ); - } + SheetViewModel& rModel = *maSheetViews.back(); + + BinAddress aSecondPos; + sal_Int32 nActivePaneId; + sal_uInt8 nFlags; + rModel.mfSplitX = rStrm.readDouble(); + rModel.mfSplitY = rStrm.readDouble(); + rStrm >> aSecondPos; + nActivePaneId = rStrm.readInt32(); + nFlags = rStrm.readuChar(); + + rModel.maSecondPos = getAddressConverter().createValidCellAddress( aSecondPos, getSheetIndex(), false ); + rModel.mnActivePaneId = lclGetOoxPaneId( nActivePaneId, XML_topLeft ); + rModel.mnPaneState = getFlagValue( nFlags, BIFF12_PANE_FROZEN, getFlagValue( nFlags, BIFF12_PANE_FROZENNOSPLIT, XML_frozen, XML_frozenSplit ), XML_split ); } void SheetViewSettings::importSelection( SequenceInputStream& rStrm ) { OSL_ENSURE( !maSheetViews.empty(), "SheetViewSettings::importSelection - missing sheet view model" ); - if( !maSheetViews.empty() ) - { - // pane this selection belongs to - sal_Int32 nPaneId = rStrm.readInt32(); - PaneSelectionModel& rPaneSel = maSheetViews.back()->createPaneSelection( lclGetOoxPaneId( nPaneId, -1 ) ); - // cursor position - BinAddress aActiveCell; - rStrm >> aActiveCell; - rPaneSel.mnActiveCellId = rStrm.readInt32(); - rPaneSel.maActiveCell = getAddressConverter().createValidCellAddress( aActiveCell, getSheetIndex(), false ); - // selection - BinRangeList aSelection; - rStrm >> aSelection; - rPaneSel.maSelection.RemoveAll(); - getAddressConverter().convertToCellRangeList( rPaneSel.maSelection, aSelection, getSheetIndex(), false ); - } + if( maSheetViews.empty() ) + return; + + // pane this selection belongs to + sal_Int32 nPaneId = rStrm.readInt32(); + PaneSelectionModel& rPaneSel = maSheetViews.back()->createPaneSelection( lclGetOoxPaneId( nPaneId, -1 ) ); + // cursor position + BinAddress aActiveCell; + rStrm >> aActiveCell; + rPaneSel.mnActiveCellId = rStrm.readInt32(); + rPaneSel.maActiveCell = getAddressConverter().createValidCellAddress( aActiveCell, getSheetIndex(), false ); + // selection + BinRangeList aSelection; + rStrm >> aSelection; + rPaneSel.maSelection.RemoveAll(); + getAddressConverter().convertToCellRangeList( rPaneSel.maSelection, aSelection, getSheetIndex(), false ); } void SheetViewSettings::importChartSheetView( SequenceInputStream& rStrm ) @@ -601,22 +601,22 @@ void ViewSettings::finalizeImport() maOleSize.aEnd.SetTab( nActiveSheet ); const ScRange* pVisibleArea = mbValidOleSize ? &maOleSize : ContainerHelper::getMapElement( maSheetUsedAreas, nActiveSheet ); - if( pVisibleArea ) + if( !pVisibleArea ) + return; + + // calculate the visible area in units of 1/100 mm + PropertySet aRangeProp( getCellRangeFromDoc( *pVisibleArea ) ); + css::awt::Point aPos; + css::awt::Size aSize; + if( aRangeProp.getProperty( aPos, PROP_Position ) && aRangeProp.getProperty( aSize, PROP_Size ) ) { - // calculate the visible area in units of 1/100 mm - PropertySet aRangeProp( getCellRangeFromDoc( *pVisibleArea ) ); - css::awt::Point aPos; - css::awt::Size aSize; - if( aRangeProp.getProperty( aPos, PROP_Position ) && aRangeProp.getProperty( aSize, PROP_Size ) ) - { - // set the visible area as sequence of long at the media descriptor - Sequence< sal_Int32 > aWinExtent( 4 ); - aWinExtent[ 0 ] = aPos.X; - aWinExtent[ 1 ] = aPos.Y; - aWinExtent[ 2 ] = aPos.X + aSize.Width; - aWinExtent[ 3 ] = aPos.Y + aSize.Height; - getBaseFilter().getMediaDescriptor()[ "WinExtent" ] <<= aWinExtent; - } + // set the visible area as sequence of long at the media descriptor + Sequence< sal_Int32 > aWinExtent( 4 ); + aWinExtent[ 0 ] = aPos.X; + aWinExtent[ 1 ] = aPos.Y; + aWinExtent[ 2 ] = aPos.X + aSize.Width; + aWinExtent[ 3 ] = aPos.Y + aSize.Height; + getBaseFilter().getMediaDescriptor()[ "WinExtent" ] <<= aWinExtent; } } diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx index 892e2e1bd2d2..9c604ca83a19 100644 --- a/sc/source/filter/oox/workbookhelper.cxx +++ b/sc/source/filter/oox/workbookhelper.cxx @@ -611,26 +611,25 @@ void WorkbookGlobals::initialize() void WorkbookGlobals::finalize() { // set some document properties needed after import - if( mrBaseFilter.isImportFilter() ) - { - // #i74668# do not insert default sheets - mpDocShell->SetEmpty(false); - // enable automatic update of linked sheets and DDE links - mpDoc->EnableExecuteLink(true); - // #i79826# enable updating automatic row height after loading the document - mpDoc->UnlockAdjustHeight(); - - // #i76026# enable Undo after loading the document - mpDoc->EnableUndo(true); - - // disable editing read-only documents (e.g. from read-only files) - mpDoc->EnableChangeReadOnly(false); - // #111099# open forms in alive mode (has no effect, if no controls in document) - ScDrawLayer* pModel = mpDoc->GetDrawLayer(); - if (pModel) - pModel->SetOpenInDesignMode(false); + if( !mrBaseFilter.isImportFilter() ) + return; - } + // #i74668# do not insert default sheets + mpDocShell->SetEmpty(false); + // enable automatic update of linked sheets and DDE links + mpDoc->EnableExecuteLink(true); + // #i79826# enable updating automatic row height after loading the document + mpDoc->UnlockAdjustHeight(); + + // #i76026# enable Undo after loading the document + mpDoc->EnableUndo(true); + + // disable editing read-only documents (e.g. from read-only files) + mpDoc->EnableChangeReadOnly(false); + // #111099# open forms in alive mode (has no effect, if no controls in document) + ScDrawLayer* pModel = mpDoc->GetDrawLayer(); + if (pModel) + pModel->SetOpenInDesignMode(false); } @@ -723,57 +722,57 @@ void WorkbookHelper::finalizeWorkbookImport() // set selected sheet and positionleft/positiontop for OLE objects Reference<XViewDataSupplier> xViewDataSupplier(getDocument(), UNO_QUERY); - if (xViewDataSupplier.is()) + if (!xViewDataSupplier.is()) + return; + + Reference<XIndexAccess> xIndexAccess(xViewDataSupplier->getViewData()); + if (!(xIndexAccess.is() && xIndexAccess->getCount() > 0)) + return; + + Sequence< PropertyValue > aSeq; + if (!(xIndexAccess->getByIndex(0) >>= aSeq)) + return; + + OUString sTabName; + Reference< XNameAccess > xSheetsNC; + for (const auto& rProp : std::as_const(aSeq)) { - Reference<XIndexAccess> xIndexAccess(xViewDataSupplier->getViewData()); - if (xIndexAccess.is() && xIndexAccess->getCount() > 0) + OUString sName(rProp.Name); + if (sName == SC_ACTIVETABLE) { - Sequence< PropertyValue > aSeq; - if (xIndexAccess->getByIndex(0) >>= aSeq) + if(rProp.Value >>= sTabName) { - OUString sTabName; - Reference< XNameAccess > xSheetsNC; - for (const auto& rProp : std::as_const(aSeq)) - { - OUString sName(rProp.Name); - if (sName == SC_ACTIVETABLE) - { - if(rProp.Value >>= sTabName) - { - SCTAB nTab(0); - if (getScDocument().GetTable(sTabName, nTab)) - getScDocument().SetVisibleTab(nTab); - } - } - else if (sName == SC_TABLES) - { - rProp.Value >>= xSheetsNC; - } - } - if (xSheetsNC.is() && xSheetsNC->hasByName(sTabName)) - { - Sequence<PropertyValue> aProperties; - Any aAny = xSheetsNC->getByName(sTabName); - if ( aAny >>= aProperties ) - { - for (const auto& rProp : std::as_const(aProperties)) - { - OUString sName(rProp.Name); - if (sName == SC_POSITIONLEFT) - { - SCCOL nPosLeft = *o3tl::doAccess<SCCOL>(rProp.Value); - getScDocument().SetPosLeft(nPosLeft); - } - else if (sName == SC_POSITIONTOP) - { - SCROW nPosTop = *o3tl::doAccess<SCROW>(rProp.Value); - getScDocument().SetPosTop(nPosTop); - } - } - } - } + SCTAB nTab(0); + if (getScDocument().GetTable(sTabName, nTab)) + getScDocument().SetVisibleTab(nTab); } } + else if (sName == SC_TABLES) + { + rProp.Value >>= xSheetsNC; + } + } + if (!(xSheetsNC.is() && xSheetsNC->hasByName(sTabName))) + return; + + Sequence<PropertyValue> aProperties; + Any aAny = xSheetsNC->getByName(sTabName); + if ( !(aAny >>= aProperties) ) + return; + + for (const auto& rProp : std::as_const(aProperties)) + { + OUString sName(rProp.Name); + if (sName == SC_POSITIONLEFT) + { + SCCOL nPosLeft = *o3tl::doAccess<SCCOL>(rProp.Value); + getScDocument().SetPosLeft(nPosLeft); + } + else if (sName == SC_POSITIONTOP) + { + SCROW nPosTop = *o3tl::doAccess<SCROW>(rProp.Value); + getScDocument().SetPosTop(nPosTop); + } } } diff --git a/sc/source/filter/oox/worksheetbuffer.cxx b/sc/source/filter/oox/worksheetbuffer.cxx index 8a20e2520c0f..bb4f156aaba7 100644 --- a/sc/source/filter/oox/worksheetbuffer.cxx +++ b/sc/source/filter/oox/worksheetbuffer.cxx @@ -112,29 +112,29 @@ OUString WorksheetBuffer::getCalcSheetName( sal_Int32 nWorksheet ) const void WorksheetBuffer::convertSheetNameRef( OUString& sSheetNameRef ) const { - if( sSheetNameRef.startsWith("#") ) + if( !sSheetNameRef.startsWith("#") ) + return; + + sal_Int32 nSepPos = sSheetNameRef.lastIndexOf( '!' ); + if( nSepPos <= 0 ) + return; + + // Do not attempt to blindly convert '#SheetName!A1' to + // '#SheetName.A1', it can be #SheetName!R1C1 as well. Hyperlink + // handler has to handle all, but prefer '#SheetName.A1' if + // possible. + if (nSepPos < sSheetNameRef.getLength() - 1) { - sal_Int32 nSepPos = sSheetNameRef.lastIndexOf( '!' ); - if( nSepPos > 0 ) - { - // Do not attempt to blindly convert '#SheetName!A1' to - // '#SheetName.A1', it can be #SheetName!R1C1 as well. Hyperlink - // handler has to handle all, but prefer '#SheetName.A1' if - // possible. - if (nSepPos < sSheetNameRef.getLength() - 1) - { - ScRange aRange; - if ((aRange.ParseAny( sSheetNameRef.copy( nSepPos + 1 ), &getScDocument(), - formula::FormulaGrammar::CONV_XL_R1C1) & ScRefFlags::VALID) == ScRefFlags::ZERO) - sSheetNameRef = sSheetNameRef.replaceAt( nSepPos, 1, OUString( '.' ) ); - } - // #i66592# convert sheet names that have been renamed on import - OUString aSheetName = sSheetNameRef.copy( 1, nSepPos - 1 ); - OUString aCalcName = getCalcSheetName( aSheetName ); - if( !aCalcName.isEmpty() ) - sSheetNameRef = sSheetNameRef.replaceAt( 1, nSepPos - 1, aCalcName ); - } + ScRange aRange; + if ((aRange.ParseAny( sSheetNameRef.copy( nSepPos + 1 ), &getScDocument(), + formula::FormulaGrammar::CONV_XL_R1C1) & ScRefFlags::VALID) == ScRefFlags::ZERO) + sSheetNameRef = sSheetNameRef.replaceAt( nSepPos, 1, OUString( '.' ) ); } + // #i66592# convert sheet names that have been renamed on import + OUString aSheetName = sSheetNameRef.copy( 1, nSepPos - 1 ); + OUString aCalcName = getCalcSheetName( aSheetName ); + if( !aCalcName.isEmpty() ) + sSheetNameRef = sSheetNameRef.replaceAt( 1, nSepPos - 1, aCalcName ); } sal_Int16 WorksheetBuffer::getCalcSheetIndex( const OUString& rWorksheetName ) const diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx index 9f92491780f2..e7889b5e0d37 100644 --- a/sc/source/filter/oox/worksheethelper.cxx +++ b/sc/source/filter/oox/worksheethelper.cxx @@ -758,68 +758,68 @@ void WorksheetGlobals::setColumnModel( const ColumnModel& rModel ) // convert 1-based OOXML column indexes to 0-based API column indexes sal_Int32 nFirstCol = rModel.maRange.mnFirst - 1; sal_Int32 nLastCol = rModel.maRange.mnLast - 1; - if( getAddressConverter().checkCol( nFirstCol, true ) && (nFirstCol <= nLastCol) ) + if( !(getAddressConverter().checkCol( nFirstCol, true ) && (nFirstCol <= nLastCol)) ) + return; + + // Validate last column index. + // If last column is equal to last possible column, Excel adds one + // more. We do that also in XclExpColinfo::SaveXml() and for 1024 end + // up with 1025 instead, which would lead to excess columns in + // checkCol(). Cater for this oddity. + if (nLastCol == mrMaxApiPos.Col() + 1) + --nLastCol; + // This is totally fouled up. If we saved 1025 and the file is saved + // with Excel again, it increments the value to 1026. + else if (nLastCol == mrMaxApiPos.Col() + 2) + nLastCol -= 2; + // Excel may add a column range for the remaining columns (with + // <cols><col .../></cols>), even if not used or only used to grey out + // columns in page break view. Don't let that trigger overflow warning, + // so check for the last possible column. If there really is content in + // the range that should be caught anyway. + else if (nLastCol == getAddressConverter().getMaxXlsAddress().Col()) + nLastCol = mrMaxApiPos.Col(); + // User may have applied custom column widths to arbitrary excess + // columns. Ignore those and don't track as overflow columns (false). + // Effectively this does the same as the above cases, just keep them + // for explanation. + // Actual data present should trigger the overflow detection later. + else if( !getAddressConverter().checkCol( nLastCol, false ) ) + nLastCol = mrMaxApiPos.Col(); + // try to find entry in column model map that is able to merge with the passed model + bool bInsertModel = true; + if( !maColModels.empty() ) { - // Validate last column index. - // If last column is equal to last possible column, Excel adds one - // more. We do that also in XclExpColinfo::SaveXml() and for 1024 end - // up with 1025 instead, which would lead to excess columns in - // checkCol(). Cater for this oddity. - if (nLastCol == mrMaxApiPos.Col() + 1) - --nLastCol; - // This is totally fouled up. If we saved 1025 and the file is saved - // with Excel again, it increments the value to 1026. - else if (nLastCol == mrMaxApiPos.Col() + 2) - nLastCol -= 2; - // Excel may add a column range for the remaining columns (with - // <cols><col .../></cols>), even if not used or only used to grey out - // columns in page break view. Don't let that trigger overflow warning, - // so check for the last possible column. If there really is content in - // the range that should be caught anyway. - else if (nLastCol == getAddressConverter().getMaxXlsAddress().Col()) - nLastCol = mrMaxApiPos.Col(); - // User may have applied custom column widths to arbitrary excess - // columns. Ignore those and don't track as overflow columns (false). - // Effectively this does the same as the above cases, just keep them - // for explanation. - // Actual data present should trigger the overflow detection later. - else if( !getAddressConverter().checkCol( nLastCol, false ) ) - nLastCol = mrMaxApiPos.Col(); - // try to find entry in column model map that is able to merge with the passed model - bool bInsertModel = true; - if( !maColModels.empty() ) + // find first column model range following nFirstCol (nFirstCol < aIt->first), or end of map + ColumnModelRangeMap::iterator aIt = maColModels.upper_bound( nFirstCol ); + OSL_ENSURE( aIt == maColModels.end(), "WorksheetGlobals::setColModel - columns are unsorted" ); + // if inserting before another column model, get last free column + OSL_ENSURE( (aIt == maColModels.end()) || (nLastCol < aIt->first), "WorksheetGlobals::setColModel - multiple models of the same column" ); + if( aIt != maColModels.end() ) + nLastCol = ::std::min( nLastCol, aIt->first - 1 ); + if( aIt != maColModels.begin() ) { - // find first column model range following nFirstCol (nFirstCol < aIt->first), or end of map - ColumnModelRangeMap::iterator aIt = maColModels.upper_bound( nFirstCol ); - OSL_ENSURE( aIt == maColModels.end(), "WorksheetGlobals::setColModel - columns are unsorted" ); - // if inserting before another column model, get last free column - OSL_ENSURE( (aIt == maColModels.end()) || (nLastCol < aIt->first), "WorksheetGlobals::setColModel - multiple models of the same column" ); - if( aIt != maColModels.end() ) - nLastCol = ::std::min( nLastCol, aIt->first - 1 ); - if( aIt != maColModels.begin() ) + // go to previous map element (which may be able to merge with the passed model) + --aIt; + // the usage of upper_bound() above ensures that aIt->first is less than or equal to nFirstCol now + sal_Int32& rnLastMapCol = aIt->second.second; + OSL_ENSURE( rnLastMapCol < nFirstCol, "WorksheetGlobals::setColModel - multiple models of the same column" ); + nFirstCol = ::std::max( rnLastMapCol + 1, nFirstCol ); + if( (rnLastMapCol + 1 == nFirstCol) && (nFirstCol <= nLastCol) && aIt->second.first.isMergeable( rModel ) ) { - // go to previous map element (which may be able to merge with the passed model) - --aIt; - // the usage of upper_bound() above ensures that aIt->first is less than or equal to nFirstCol now - sal_Int32& rnLastMapCol = aIt->second.second; - OSL_ENSURE( rnLastMapCol < nFirstCol, "WorksheetGlobals::setColModel - multiple models of the same column" ); - nFirstCol = ::std::max( rnLastMapCol + 1, nFirstCol ); - if( (rnLastMapCol + 1 == nFirstCol) && (nFirstCol <= nLastCol) && aIt->second.first.isMergeable( rModel ) ) - { - // can merge with existing model, update last column index - rnLastMapCol = nLastCol; - bInsertModel = false; - } + // can merge with existing model, update last column index + rnLastMapCol = nLastCol; + bInsertModel = false; } } - if( nFirstCol <= nLastCol ) - { - // insert the column model, if it has not been merged with another - if( bInsertModel ) - maColModels[ nFirstCol ] = ColumnModelRange( rModel, nLastCol ); - // set column formatting directly - convertColumnFormat( nFirstCol, nLastCol, rModel.mnXfId ); - } + } + if( nFirstCol <= nLastCol ) + { + // insert the column model, if it has not been merged with another + if( bInsertModel ) + maColModels[ nFirstCol ] = ColumnModelRange( rModel, nLastCol ); + // set column formatting directly + convertColumnFormat( nFirstCol, nLastCol, rModel.mnXfId ); } } |