[Libreoffice-commits] core.git: Branch 'feature/ods-edit-cell-import' - sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Fri Feb 8 16:42:38 PST 2013


 sc/source/filter/xml/celltextparacontext.cxx |   37 +++++-
 sc/source/filter/xml/celltextparacontext.hxx |    3 
 sc/source/filter/xml/xmlcelli.cxx            |  158 +++++++++++++++++++++++++--
 sc/source/filter/xml/xmlcelli.hxx            |   22 +++
 sc/source/filter/xml/xmlimprt.cxx            |   17 ++
 sc/source/filter/xml/xmlimprt.hxx            |   13 ++
 6 files changed, 230 insertions(+), 20 deletions(-)

New commits:
commit a1b684eaabe9a36f762df1dac60e4053f1c84d15
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Feb 8 19:43:22 2013 -0500

    Import formatted spans correctly.
    
    There are more format types to cover. I'm not done yet.
    
    Change-Id: I42fab04f65810733e5b25fbbc2c92df7e05c05cf

diff --git a/sc/source/filter/xml/celltextparacontext.cxx b/sc/source/filter/xml/celltextparacontext.cxx
index 66c48e7..d15b715 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 75ce3f8..8401c0d 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 4e13655..88f88df 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 cbd622f..e9d7e23 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 e62ec9b..c4a5ff2 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 3ae05c0..fc5ed7a 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)
     {


More information about the Libreoffice-commits mailing list