diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-02-08 19:43:22 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-02-11 22:33:33 -0500 |
commit | fa23b694c1979254c9a045bcf51d281c29d80c8d (patch) | |
tree | fa2c6e2682139a01108494e0d1724b5dd616f8a0 | |
parent | 96d89d9cc77105cb5cf864f4392554f9613d12cf (diff) |
Import formatted spans correctly.
There are more format types to cover. I'm not done yet.
Change-Id: I42fab04f65810733e5b25fbbc2c92df7e05c05cf
-rw-r--r-- | sc/source/filter/xml/celltextparacontext.cxx | 37 | ||||
-rw-r--r-- | sc/source/filter/xml/celltextparacontext.hxx | 3 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlcelli.cxx | 158 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlcelli.hxx | 22 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlimprt.cxx | 17 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlimprt.hxx | 13 |
6 files changed, 230 insertions, 20 deletions
diff --git a/sc/source/filter/xml/celltextparacontext.cxx b/sc/source/filter/xml/celltextparacontext.cxx index 66c48e7d2447..d15b715bbf51 100644 --- a/sc/source/filter/xml/celltextparacontext.cxx +++ b/sc/source/filter/xml/celltextparacontext.cxx @@ -11,6 +11,8 @@ #include "xmlimprt.hxx" #include "xmlcelli.hxx" +#include "xmloff/nmspmap.hxx" + #include <com/sun/star/xml/sax/XAttributeList.hpp> using namespace com::sun::star; @@ -29,7 +31,7 @@ void ScXMLCellTextParaContext::StartElement(const uno::Reference<xml::sax::XAttr void ScXMLCellTextParaContext::EndElement() { if (!maContent.isEmpty()) - mrParentCxt.PushParagraphSpan(maContent); + mrParentCxt.PushParagraphSpan(maContent, OUString()); mrParentCxt.PushParagraphEnd(); } @@ -44,7 +46,7 @@ SvXMLImportContext* ScXMLCellTextParaContext::CreateChildContext( { if (!maContent.isEmpty()) { - mrParentCxt.PushParagraphSpan(maContent); + mrParentCxt.PushParagraphSpan(maContent, OUString()); maContent = OUString(); } @@ -61,9 +63,9 @@ SvXMLImportContext* ScXMLCellTextParaContext::CreateChildContext( return new SvXMLImportContext(GetImport(), nPrefix, rLocalName); } -void ScXMLCellTextParaContext::PushSpan(const OUString& rSpan) +void ScXMLCellTextParaContext::PushSpan(const OUString& rSpan, const OUString& rStyleName) { - mrParentCxt.PushParagraphSpan(rSpan); + mrParentCxt.PushParagraphSpan(rSpan, rStyleName); } ScXMLCellTextSpanContext::ScXMLCellTextSpanContext( @@ -75,12 +77,37 @@ ScXMLCellTextSpanContext::ScXMLCellTextSpanContext( void ScXMLCellTextSpanContext::StartElement(const uno::Reference<xml::sax::XAttributeList>& xAttrList) { + if (!xAttrList.is()) + return; + + OUString aLocalName; + sal_Int16 nAttrCount = xAttrList->getLength(); + + const SvXMLTokenMap& rTokenMap = GetScImport().GetCellTextSpanAttrTokenMap(); + for (sal_Int16 i = 0; i < nAttrCount; ++i) + { + sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( + xAttrList->getNameByIndex(i), &aLocalName); + + const OUString& rAttrValue = xAttrList->getValueByIndex(i); + sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName); + switch (nToken) + { + case XML_TOK_CELL_TEXT_SPAN_ATTR_STYLE_NAME: + maStyleName = rAttrValue; + break; + default: + ; + } + } } void ScXMLCellTextSpanContext::EndElement() { if (!maContent.isEmpty()) - mrParentCxt.PushSpan(maContent); + { + mrParentCxt.PushSpan(maContent, maStyleName); + } } void ScXMLCellTextSpanContext::Characters(const OUString& rChars) diff --git a/sc/source/filter/xml/celltextparacontext.hxx b/sc/source/filter/xml/celltextparacontext.hxx index 75ce3f8c76db..8401c0d77146 100644 --- a/sc/source/filter/xml/celltextparacontext.hxx +++ b/sc/source/filter/xml/celltextparacontext.hxx @@ -31,7 +31,7 @@ public: virtual SvXMLImportContext* CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList>& xAttrList); - void PushSpan(const OUString& rSpan); + void PushSpan(const OUString& rSpan, const OUString& rStyleName); }; /** @@ -40,6 +40,7 @@ public: class ScXMLCellTextSpanContext : public ScXMLImportContext { ScXMLCellTextParaContext& mrParentCxt; + OUString maStyleName; OUString maContent; public: ScXMLCellTextSpanContext(ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName, ScXMLCellTextParaContext& rParent); diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx index 4e136551e31d..88f88df6036b 100644 --- a/sc/source/filter/xml/xmlcelli.cxx +++ b/sc/source/filter/xml/xmlcelli.cxx @@ -55,10 +55,15 @@ #include <xmloff/families.hxx> #include <xmloff/numehelp.hxx> #include <xmloff/xmlnmspe.hxx> +#include "xmloff/prstylei.hxx" #include <svl/zforlist.hxx> #include <svx/svdocapt.hxx> #include <editeng/outlobj.hxx> #include <editeng/editobj.hxx> +#include "editeng/wghtitem.hxx" +#include "editeng/colritem.hxx" +#include "editeng/fhgtitem.hxx" +#include "editeng/postitem.hxx" #include <svx/unoapi.hxx> #include <svl/languageoptions.hxx> #include <sax/tools/converter.hxx> @@ -96,7 +101,9 @@ using namespace xmloff::token; using rtl::OUString; -//------------------------------------------------------------------ + +ScXMLTableRowCellContext::ParaFormat::ParaFormat(ScEditEngineDefaulter& rEditEngine) : + maItemSet(rEditEngine.GetEmptyItemSet()) {} ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport, sal_uInt16 nPrfx, @@ -107,6 +114,7 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport, const sal_Int32 nTempRepeatedRows ) : ScXMLImportContext(rImport, nPrfx, rLName), mpEditEngine(GetScImport().GetEditEngine()), + mnCurParagraph(0), pDetectiveObjVec(NULL), pCellRangeSource(NULL), fValue(0.0), @@ -125,7 +133,8 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport, bSolarMutexLocked(false), bFormulaTextResult(false), mbPossibleErrorCell(false), - mbCheckWithCompilerForError(false) + mbCheckWithCompilerForError(false), + mbEditEngineHasText(false) { rtl::math::setNan(&fValue); // NaN by default mpEditEngine->Clear(); @@ -302,15 +311,127 @@ bool cellExists( const ScAddress& rCellPos ) } -void ScXMLTableRowCellContext::PushParagraphSpan(const OUString& rSpan) +void ScXMLTableRowCellContext::PushParagraphSpan(const OUString& rSpan, const OUString& rStyleName) { + sal_Int32 nBegin = maParagraph.getLength(); + sal_Int32 nEnd = nBegin + rSpan.getLength(); maParagraph.append(rSpan); + + if (rStyleName.isEmpty()) + return; + + // Get the style information from xmloff. + UniReference<XMLPropertySetMapper> xMapper = GetImport().GetTextImport()->GetTextImportPropertySetMapper()->getPropertySetMapper(); + if (!xMapper.is()) + // We can't do anything without the mapper. + return; + + sal_Int32 nEntryCount = xMapper->GetEntryCount(); + + SvXMLStylesContext* pAutoStyles = GetImport().GetAutoStyles(); + + // Style name for text span corresponds with the name of an automatic style. + const XMLPropStyleContext* pStyle = dynamic_cast<const XMLPropStyleContext*>( + pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TEXT_TEXT, rStyleName)); + + if (!pStyle) + // No style by that name found. + return; + + const std::vector<XMLPropertyState>& rProps = pStyle->GetProperties(); + if (rProps.empty()) + return; + + maFormats.push_back(new ParaFormat(*mpEditEngine)); + ParaFormat& rFmt = maFormats.back(); + rFmt.maSelection.nStartPara = rFmt.maSelection.nEndPara = mnCurParagraph; + rFmt.maSelection.nStartPos = nBegin; + rFmt.maSelection.nEndPos = nEnd; + + std::vector<XMLPropertyState>::const_iterator it = rProps.begin(), itEnd = rProps.end(); + for (; it != itEnd; ++it) + { + if (it->mnIndex == -1 || it->mnIndex >= nEntryCount) + continue; + + const OUString& rName = xMapper->GetEntryXMLName(it->mnIndex); + + if (rName == "font-weight") + { + SvxWeightItem aItem(WEIGHT_NORMAL, EE_CHAR_WEIGHT); + aItem.PutValue(it->maValue, MID_WEIGHT); + rFmt.maItemSet.Put(aItem); + } + else if (rName == "font-weight-asian") + { + SvxWeightItem aItem(WEIGHT_NORMAL, EE_CHAR_WEIGHT_CJK); + aItem.PutValue(it->maValue, MID_WEIGHT); + rFmt.maItemSet.Put(aItem); + } + else if (rName == "font-weight-complex") + { + SvxWeightItem aItem(WEIGHT_NORMAL, EE_CHAR_WEIGHT_CTL); + aItem.PutValue(it->maValue, MID_WEIGHT); + rFmt.maItemSet.Put(aItem); + } + else if (rName == "font-size") + { + SvxFontHeightItem aItem(240, 100, EE_CHAR_FONTHEIGHT); + aItem.PutValue(it->maValue, MID_FONTHEIGHT); + rFmt.maItemSet.Put(aItem); + } + else if (rName == "font-size-asian") + { + SvxFontHeightItem aItem(240, 100, EE_CHAR_FONTHEIGHT_CJK); + aItem.PutValue(it->maValue, MID_FONTHEIGHT); + rFmt.maItemSet.Put(aItem); + } + else if (rName == "font-size-complex") + { + SvxFontHeightItem aItem(240, 100, EE_CHAR_FONTHEIGHT_CTL); + aItem.PutValue(it->maValue, MID_FONTHEIGHT); + rFmt.maItemSet.Put(aItem); + } + else if (rName == "font-style") + { + SvxPostureItem aItem(ITALIC_NONE, EE_CHAR_ITALIC); + aItem.PutValue(it->maValue, MID_POSTURE); + rFmt.maItemSet.Put(aItem); + } + else if (rName == "font-style-asian") + { + SvxPostureItem aItem(ITALIC_NONE, EE_CHAR_ITALIC_CJK); + aItem.PutValue(it->maValue, MID_POSTURE); + rFmt.maItemSet.Put(aItem); + } + else if (rName == "font-style-complex") + { + SvxPostureItem aItem(ITALIC_NONE, EE_CHAR_ITALIC_CTL); + aItem.PutValue(it->maValue, MID_POSTURE); + rFmt.maItemSet.Put(aItem); + } + else if (rName == "color") + { + SvxColorItem aItem(EE_CHAR_COLOR); + aItem.PutValue(it->maValue, 0); + rFmt.maItemSet.Put(aItem); + } + } } void ScXMLTableRowCellContext::PushParagraphEnd() { - mpEditEngine->InsertParagraph( - mpEditEngine->GetParagraphCount(), maParagraph.makeStringAndClear()); + // EditEngine always has at least one paragraph even when its content is empty. + + if (mbEditEngineHasText) + mpEditEngine->InsertParagraph(mpEditEngine->GetParagraphCount(), maParagraph.makeStringAndClear()); + else + { + mpEditEngine->SetText(maParagraph.makeStringAndClear()); + mbEditEngineHasText = true; + } + + ++mnCurParagraph; } SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPrefix, @@ -674,7 +795,7 @@ void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const } else if (!rtl::math::isNan(fValue)) { - if (mpEditEngine->GetParagraphCount()) + if (mbEditEngineHasText) pFCell->SetHybridValueString(fValue, mpEditEngine->GetText(0)); else pFCell->SetHybridDouble(fValue); @@ -700,7 +821,7 @@ void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos, OUString aCellString; if (maStringValue) aCellString = *maStringValue; - else if (mpEditEngine->GetParagraphCount()) + else if (mbEditEngineHasText) aCellString = mpEditEngine->GetText(0); else if ( nCurrentCol > 0 && pOUText && !pOUText->isEmpty() ) aCellString = *pOUText; @@ -735,8 +856,23 @@ void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos, ScDocument* pDoc = rXMLImport.GetDocument(); if (maStringValue) pNewCell = ScBaseCell::CreateTextCell( *maStringValue, pDoc ); - else if (mpEditEngine->GetParagraphCount()) - pNewCell = new ScEditCell(mpEditEngine->CreateTextObject(), pDoc, pDoc->GetEditPool()); + else if (mbEditEngineHasText) + { + if (maFormats.empty() && mpEditEngine->GetParagraphCount() == 1) + { + // This is a normal text without format runs. + pNewCell = new ScStringCell(mpEditEngine->GetText()); + } + else + { + // This text either has format runs, or consists of multiple lines. + ParaFormatsType::const_iterator it = maFormats.begin(), itEnd = maFormats.end(); + for (; it != itEnd; ++it) + mpEditEngine->QuickSetAttribs(it->maItemSet, it->maSelection); + + pNewCell = new ScEditCell(mpEditEngine->CreateTextObject(), pDoc, pDoc->GetEditPool()); + } + } else if ( nCurrentCol > 0 && pOUText && !pOUText->isEmpty() ) pNewCell = ScBaseCell::CreateTextCell( *pOUText, pDoc ); @@ -942,7 +1078,7 @@ void ScXMLTableRowCellContext::AddNonFormulaCell( const ScAddress& rCellPos ) if( cellExists(rCellPos) && CellsAreRepeated() ) pOUText.reset( getOutputString(rXMLImport.GetDocument(), rCellPos) ); - if (!mpEditEngine->GetParagraphCount() && !pOUText && !maStringValue) + if (!mbEditEngineHasText && !pOUText && !maStringValue) bIsEmpty = true; } @@ -1092,7 +1228,7 @@ void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos ) // - has an "Err:[###]" (where "[###]" is an error number) void ScXMLTableRowCellContext::HasSpecialCaseFormulaText() { - if (!mpEditEngine->GetParagraphCount()) + if (!mbEditEngineHasText) return; OUString aStr = mpEditEngine->GetText(0); diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx index cbd622fdc12b..e9d7e2361df8 100644 --- a/sc/source/filter/xml/xmlcelli.hxx +++ b/sc/source/filter/xml/xmlcelli.hxx @@ -23,8 +23,12 @@ #include "XMLCellRangeSourceContext.hxx" #include "importcontext.hxx" #include "formula/grammar.hxx" +#include "svl/itemset.hxx" +#include "editeng/editdata.hxx" + #include <boost/optional.hpp> #include <boost/scoped_ptr.hpp> +#include <boost/ptr_container/ptr_vector.hpp> class ScXMLImport; class ScFormulaCell; @@ -41,6 +45,17 @@ class ScXMLTableRowCellContext : public ScXMLImportContext ScEditEngineDefaulter* mpEditEngine; OUStringBuffer maParagraph; + sal_uInt16 mnCurParagraph; + + struct ParaFormat + { + SfxItemSet maItemSet; + ESelection maSelection; + + ParaFormat(ScEditEngineDefaulter& rEditEngine); + }; + typedef boost::ptr_vector<ParaFormat> ParaFormatsType; + ParaFormatsType maFormats; boost::scoped_ptr< ScXMLAnnotationData > mxAnnotationData; ScMyImpDetectiveObjVec* pDetectiveObjVec; @@ -58,8 +73,9 @@ class ScXMLTableRowCellContext : public ScXMLImportContext bool bIsFirstTextImport; bool bSolarMutexLocked; bool bFormulaTextResult; - bool mbPossibleErrorCell; - bool mbCheckWithCompilerForError; + bool mbPossibleErrorCell; + bool mbCheckWithCompilerForError; + bool mbEditEngineHasText; sal_Int16 GetCellType(const rtl::OUString& sOUValue) const; @@ -103,7 +119,7 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList ); - void PushParagraphSpan(const OUString& rSpan); + void PushParagraphSpan(const OUString& rSpan, const OUString& rStyleName); void PushParagraphEnd(); void SetAnnotation( const ScAddress& rPosition ); diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx index e62ec9b651ad..c4a5ff21a3c6 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -1857,6 +1857,21 @@ const SvXMLTokenMap& ScXMLImport::GetCellTextParaElemTokenMap() return *pCellTextParaElemTokemMap; } +const SvXMLTokenMap& ScXMLImport::GetCellTextSpanAttrTokenMap() +{ + if (!pCellTextSpanAttrTokemMap) + { + static SvXMLTokenMapEntry aMap[] = + { + { XML_NAMESPACE_TEXT, XML_STYLE_NAME, XML_TOK_CELL_TEXT_SPAN_ATTR_STYLE_NAME }, + XML_TOKEN_MAP_END + }; + + pCellTextSpanAttrTokemMap = new SvXMLTokenMap(aMap); + } + return *pCellTextSpanAttrTokemMap; +} + SvXMLImportContext *ScXMLImport::CreateContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference<xml::sax::XAttributeList>& xAttrList ) @@ -1980,6 +1995,7 @@ ScXMLImport::ScXMLImport( pDataPilotMemberAttrTokenMap( 0 ), pConsolidationAttrTokenMap( 0 ), pCellTextParaElemTokemMap(NULL), + pCellTextSpanAttrTokemMap(NULL), aTables(*this), pMyNamedExpressions(NULL), pMyLabelRanges(NULL), @@ -2118,6 +2134,7 @@ ScXMLImport::~ScXMLImport() throw() delete pDataPilotMemberAttrTokenMap; delete pConsolidationAttrTokenMap; delete pCellTextParaElemTokemMap; + delete pCellTextSpanAttrTokemMap; delete pChangeTrackingImportHelper; delete pNumberFormatAttributesExportHelper; diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx index 3ae05c0abefc..fc5ed7a867c4 100644 --- a/sc/source/filter/xml/xmlimprt.hxx +++ b/sc/source/filter/xml/xmlimprt.hxx @@ -682,11 +682,22 @@ enum ScXMLConsolidationAttrTokens XML_TOK_CONSOLIDATION_ATTR_LINK_TO_SOURCE }; +/** + * Tokens for elements that come under <text:p> + */ enum ScXMLCellTextParaElemTokens { XML_TOK_CELL_TEXT_SPAN }; +/** + * Tokens for attributes for <text:span> + */ +enum ScXMLCellTextSpanAttrTokens +{ + XML_TOK_CELL_TEXT_SPAN_ATTR_STYLE_NAME +}; + class SvXMLTokenMap; class XMLShapeImportHelper; class ScXMLChangeTrackingImportHelper; @@ -854,6 +865,7 @@ class ScXMLImport: public SvXMLImport, boost::noncopyable SvXMLTokenMap *pDataPilotMemberAttrTokenMap; SvXMLTokenMap *pConsolidationAttrTokenMap; SvXMLTokenMap *pCellTextParaElemTokemMap; + SvXMLTokenMap *pCellTextSpanAttrTokemMap; ScMyTables aTables; @@ -1020,6 +1032,7 @@ public: const SvXMLTokenMap& GetDataPilotMemberAttrTokenMap(); const SvXMLTokenMap& GetConsolidationAttrTokenMap(); const SvXMLTokenMap& GetCellTextParaElemTokenMap(); + const SvXMLTokenMap& GetCellTextSpanAttrTokenMap(); void AddNamedExpression(ScMyNamedExpression* pMyNamedExpression) { |