diff options
Diffstat (limited to 'sc/source/filter/oox/extlstcontext.cxx')
-rw-r--r-- | sc/source/filter/oox/extlstcontext.cxx | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/sc/source/filter/oox/extlstcontext.cxx b/sc/source/filter/oox/extlstcontext.cxx new file mode 100644 index 000000000..67d52fc69 --- /dev/null +++ b/sc/source/filter/oox/extlstcontext.cxx @@ -0,0 +1,432 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <memory> +#include <extlstcontext.hxx> +#include <worksheethelper.hxx> +#include <oox/core/contexthandler.hxx> +#include <oox/helper/attributelist.hxx> +#include <oox/token/namespaces.hxx> +#include <oox/token/tokens.hxx> +#include <colorscale.hxx> +#include <condformatbuffer.hxx> +#include <condformatcontext.hxx> +#include <document.hxx> +#include <worksheetfragment.hxx> +#include <workbookfragment.hxx> +#include <stylesbuffer.hxx> +#include <stylesfragment.hxx> +#include <SparklineFragment.hxx> + +#include <rangeutl.hxx> +#include <sal/log.hxx> + +using ::oox::core::ContextHandlerRef; +using ::oox::xls::CondFormatBuffer; + +sal_Int32 rStyleIdx = 0; + +namespace oox::xls { + +ExtCfRuleContext::ExtCfRuleContext( WorksheetContextBase& rFragment, ScDataBarFormatData* pTarget ): + WorksheetContextBase( rFragment ), + mpTarget( pTarget ), + mbFirstEntry(true) +{ +} + +ContextHandlerRef ExtCfRuleContext::onCreateContext( sal_Int32 , const AttributeList& ) +{ + return this; +} + +void ExtCfRuleContext::onStartElement( const AttributeList& rAttribs ) +{ + switch( getCurrentElement() ) + { + case XLS14_TOKEN( dataBar ): + { + ExtCfDataBarRuleRef xRule = getCondFormats().createExtCfDataBarRule(mpTarget); + xRule->importDataBar( rAttribs ); + break; + } + case XLS14_TOKEN( negativeFillColor ): + { + ExtCfDataBarRuleRef xRule = getCondFormats().createExtCfDataBarRule(mpTarget); + xRule->importNegativeFillColor( rAttribs ); + break; + } + case XLS14_TOKEN( axisColor ): + { + ExtCfDataBarRuleRef xRule = getCondFormats().createExtCfDataBarRule(mpTarget); + xRule->importAxisColor( rAttribs ); + break; + } + case XLS14_TOKEN( cfvo ): + { + ExtCfDataBarRuleRef xRule = getCondFormats().createExtCfDataBarRule(mpTarget); + xRule->importCfvo( rAttribs ); + xRule->getModel().mbIsLower = mbFirstEntry; + mbFirstEntry = false; + break; + } + default: + break; + } +} + +namespace { + bool IsSpecificTextCondMode(ScConditionMode eMode) + { + switch (eMode) + { + case ScConditionMode::BeginsWith: + case ScConditionMode::EndsWith: + case ScConditionMode::ContainsText: + case ScConditionMode::NotContainsText: + return true; + default: + break; + } + return false; + } +} + +ExtConditionalFormattingContext::ExtConditionalFormattingContext(WorksheetContextBase& rFragment) + : WorksheetContextBase(rFragment) + , nFormulaCount(0) + , nPriority(-1) + , eOperator(ScConditionMode::NONE) + , isPreviousElementF(false) +{ +} + +ContextHandlerRef ExtConditionalFormattingContext::onCreateContext(sal_Int32 nElement, const AttributeList& rAttribs) +{ + if (mpCurrentRule) + { + ScFormatEntry& rFormat = **maEntries.rbegin(); + assert(rFormat.GetType() == ScFormatEntry::Type::Iconset); + ScIconSetFormat& rIconSet = static_cast<ScIconSetFormat&>(rFormat); + ScDocument& rDoc = getScDocument(); + SCTAB nTab = getSheetIndex(); + ScAddress aPos(0, 0, nTab); + mpCurrentRule->SetData(&rIconSet, &rDoc, aPos); + mpCurrentRule.reset(); + } + if (nElement == XLS14_TOKEN(cfRule)) + { + OUString aType = rAttribs.getString(XML_type, OUString()); + OUString aId = rAttribs.getString(XML_id, OUString()); + nPriority = rAttribs.getInteger( XML_priority, -1 ); + maPriorities.push_back(nPriority); + maModel.nPriority = nPriority; + + if (aType == "dataBar") + { + // an ext entry does not need to have an existing corresponding entry + ExtLst::const_iterator aExt = getExtLst().find( aId ); + if(aExt == getExtLst().end()) + return nullptr; + + ScDataBarFormatData* pInfo = aExt->second; + if (!pInfo) + { + return nullptr; + } + return new ExtCfRuleContext( *this, pInfo ); + } + else if (aType == "iconSet") + { + ScDocument& rDoc = getScDocument(); + mpCurrentRule.reset(new IconSetRule(*this)); + maEntries.push_back(std::make_unique<ScIconSetFormat>(&rDoc)); + return new IconSetContext(*this, mpCurrentRule.get()); + } + else if (aType == "cellIs") + { + sal_Int32 aToken = rAttribs.getToken( XML_operator, XML_TOKEN_INVALID ); + eOperator = CondFormatBuffer::convertToInternalOperator(aToken); + maModel.eOperator = eOperator; + return this; + } + else if (aType == "containsText") + { + eOperator = ScConditionMode::ContainsText; + maModel.eOperator = eOperator; + return this; + } + else if (aType == "notContainsText") + { + eOperator = ScConditionMode::NotContainsText; + maModel.eOperator = eOperator; + return this; + } + else if (aType == "beginsWith") + { + eOperator = ScConditionMode::BeginsWith; + maModel.eOperator = eOperator; + return this; + } + else if (aType == "endsWith") + { + eOperator = ScConditionMode::EndsWith; + maModel.eOperator = eOperator; + return this; + } + else if (aType == "expression") + { + eOperator = ScConditionMode::Direct; + maModel.eOperator = eOperator; + return this; + } + else + { + SAL_WARN("sc", "unhandled XLS14_TOKEN(cfRule) with type: " << aType); + } + } + else if (nElement == XLS14_TOKEN( dxf )) + { + return new DxfContext( *this, getStyles().createExtDxf() ); + } + else if (nElement == XM_TOKEN( sqref ) || nElement == XM_TOKEN( f )) + { + if(nElement == XM_TOKEN( f )) + nFormulaCount++; + return this; + } + + return nullptr; +} + +void ExtConditionalFormattingContext::onStartElement(const AttributeList& /*Attribs*/) +{ +} + +void ExtConditionalFormattingContext::onCharacters(const OUString& rCharacters) +{ + switch (getCurrentElement()) + { + case XM_TOKEN(f): + { + aChars = rCharacters; + isPreviousElementF = true; + } + break; + case XM_TOKEN(sqref): + { + aChars = rCharacters; + } + break; + } + +} + +void ExtConditionalFormattingContext::onEndElement() +{ + switch (getCurrentElement()) + { + case XM_TOKEN(f): + { + if(!IsSpecificTextCondMode(eOperator) || nFormulaCount == 2) + maModel.aFormula = aChars; + } + break; + case XLS14_TOKEN( cfRule ): + { + getStyles().getExtDxfs().forEachMem( &Dxf::finalizeImport ); + maModel.aStyle = getStyles().createExtDxfStyle(rStyleIdx); + rStyleIdx++; + nFormulaCount = 0; + maModels.push_back(maModel); + } + break; + case XM_TOKEN(sqref): + { + ScRangeList aRange; + ScDocument& rDoc = getScDocument(); + bool bSuccess = ScRangeStringConverter::GetRangeListFromString(aRange, aChars, rDoc, formula::FormulaGrammar::CONV_XL_OOX); + if (!bSuccess || aRange.empty()) + break; + + SCTAB nTab = getSheetIndex(); + for (size_t i = 0; i < aRange.size(); ++i) + { + aRange[i].aStart.SetTab(nTab); + aRange[i].aEnd.SetTab(nTab); + } + + if (maModels.size() > 1) + { + std::sort(maModels.begin(), maModels.end(), + [](const ExtCondFormatRuleModel& lhs, const ExtCondFormatRuleModel& rhs) { + return lhs.nPriority < rhs.nPriority; + }); + } + + if (isPreviousElementF) // sqref can be alone in some cases. + { + for (size_t i = 0; i < maModels.size(); ++i) + { + ScAddress rPos = aRange.GetTopLeftCorner(); + ScCondFormatEntry* pEntry = new ScCondFormatEntry(maModels[i].eOperator, maModels[i].aFormula, "", rDoc, + rPos, maModels[i].aStyle, "", "", + formula::FormulaGrammar::GRAM_OOXML , + formula::FormulaGrammar::GRAM_OOXML, + ScFormatEntry::Type::ExtCondition ); + maEntries.push_back(std::unique_ptr<ScFormatEntry>(pEntry)); + } + + assert(maModels.size() == maPriorities.size()); + maModels.clear(); + } + + std::vector< std::unique_ptr<ExtCfCondFormat> >& rExtFormats = getCondFormats().importExtCondFormat(); + rExtFormats.push_back(std::make_unique<ExtCfCondFormat>(aRange, maEntries, &maPriorities)); + + maPriorities.clear(); + isPreviousElementF = false; + } + break; + default: + break; + } +} + +ExtLstLocalContext::ExtLstLocalContext( WorksheetContextBase& rFragment, ScDataBarFormatData* pTarget ): + WorksheetContextBase(rFragment), + mpTarget(pTarget) +{ +} + +ContextHandlerRef ExtLstLocalContext::onCreateContext( sal_Int32 nElement, const AttributeList& ) +{ + switch( getCurrentElement() ) + { + case XLS_TOKEN( extLst ): + if(nElement == XLS_TOKEN( ext )) + return this; + else + return nullptr; + case XLS_TOKEN( ext ): + if (nElement == XLS14_TOKEN( id )) + return this; + else + return nullptr; + } + return nullptr; +} + +void ExtLstLocalContext::onStartElement( const AttributeList& ) +{ + switch( getCurrentElement() ) + { + case XLS14_TOKEN( id ): + break; + } +} + +void ExtLstLocalContext::onCharacters( const OUString& rChars ) +{ + if (getCurrentElement() == XLS14_TOKEN( id )) + { + getExtLst().insert( std::pair< OUString, ScDataBarFormatData*>(rChars, mpTarget) ); + } +} + +ExtGlobalContext::ExtGlobalContext( WorksheetContextBase& rFragment ): + WorksheetContextBase(rFragment) +{ +} + +ContextHandlerRef ExtGlobalContext::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/ ) +{ + switch (nElement) + { + case XLS14_TOKEN(conditionalFormatting): return new ExtConditionalFormattingContext(*this); + case XLS14_TOKEN(dataValidations): return new ExtDataValidationsContext(*this); + case XLS14_TOKEN(sparklineGroups): return new SparklineGroupsContext(*this); + } + return this; +} + +void ExtGlobalContext::onStartElement( const AttributeList& /*rAttribs*/ ) +{ +} + +ExtLstGlobalContext::ExtLstGlobalContext( WorksheetFragment& rFragment ): + WorksheetContextBase(rFragment) +{ +} + +ContextHandlerRef ExtLstGlobalContext::onCreateContext( sal_Int32 nElement, const AttributeList& ) +{ + if (nElement == XLS_TOKEN( ext )) + return new ExtGlobalContext( *this ); + + return this; +} + +ExtGlobalWorkbookContext::ExtGlobalWorkbookContext( WorkbookContextBase& rFragment ): + WorkbookContextBase(rFragment) +{ +} + +ContextHandlerRef ExtGlobalWorkbookContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) +{ + if (nElement == LOEXT_TOKEN(extCalcPr)) + { + ScDocument& rDoc = getScDocument(); + sal_Int32 nToken = rAttribs.getToken( XML_stringRefSyntax, XML_CalcA1 ); + ScCalcConfig aCalcConfig = rDoc.GetCalcConfig(); + + switch( nToken ) + { + case XML_CalcA1: + aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_OOO ); + break; + case XML_ExcelA1: + aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_XL_A1 ); + break; + case XML_ExcelR1C1: + aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_XL_R1C1 ); + break; + case XML_CalcA1ExcelA1: + aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_A1_XL_A1 ); + break; + default: + aCalcConfig.SetStringRefSyntax( formula::FormulaGrammar::CONV_UNSPECIFIED ); + break; + } + rDoc.SetCalcConfig(aCalcConfig); + } + + return this; +} + +void ExtGlobalWorkbookContext::onStartElement( const AttributeList& /*rAttribs*/ ) +{ +} + +ExtLstGlobalWorkbookContext::ExtLstGlobalWorkbookContext( WorkbookFragment& rFragment ): + WorkbookContextBase(rFragment) +{ +} + +ContextHandlerRef ExtLstGlobalWorkbookContext::onCreateContext( sal_Int32 nElement, const AttributeList& ) +{ + if (nElement == XLS_TOKEN( ext )) + return new ExtGlobalWorkbookContext( *this ); + + return this; +} + +} //namespace oox::xls + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |