[Libreoffice-commits] core.git: 6 commits - editeng/source sc/inc sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Sun Aug 25 11:48:31 PDT 2013


 editeng/source/editeng/editobj.cxx  |   40 ++----
 sc/inc/editutil.hxx                 |    3 
 sc/inc/formulacell.hxx              |    1 
 sc/source/core/data/formulacell.cxx |    5 
 sc/source/core/tool/editutil.cxx    |  168 +++++++++++++-------------
 sc/source/filter/xml/xmlexprt.cxx   |  227 +++++++++++++++++++++++++++++++++---
 sc/source/filter/xml/xmlexprt.hxx   |    6 
 7 files changed, 329 insertions(+), 121 deletions(-)

New commits:
commit fd4d8cee4b8c3bc7ec50d30c25090bfe61fd8037
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Sun Aug 25 14:42:37 2013 -0400

    Now we don't need to increment progress bar on every edit cell.
    
    Change-Id: Id5d460c134c6683a4e876856575ce269a43ea66f

diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 42cac6d..980b025 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -3340,18 +3340,14 @@ void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount)
     WriteAnnotation(aCell);
     WriteDetective(aCell);
 
-    bool bEditCell = false;
-
     if (!bIsEmpty)
     {
         if (aCell.nType == table::CellContentType_TEXT && aCell.maBaseCell.meType == CELLTYPE_EDIT)
         {
-            bEditCell = true;
             WriteEditCell(aCell.maBaseCell.mpEditText);
         }
         else if (aCell.nType == table::CellContentType_FORMULA && IsMultiLineFormulaCell(aCell))
         {
-            bEditCell = true;
             WriteMultiLineFormulaResult(aCell.maBaseCell.mpFormula);
         }
         else
@@ -3364,7 +3360,7 @@ void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount)
     }
     WriteShapes(aCell);
     if (!bIsEmpty)
-        IncrementProgressBar(bEditCell);
+        IncrementProgressBar(false);
 }
 
 void ScXMLExport::WriteEditCell(const EditTextObject* pText)
@@ -5006,10 +5002,10 @@ void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uIn
         XML_NAMESPACE_PRESENTATION );
 }
 
-void ScXMLExport::IncrementProgressBar(bool bEditCell, sal_Int32 nInc)
+void ScXMLExport::IncrementProgressBar(bool bFlush, sal_Int32 nInc)
 {
     nProgressCount += nInc;
-    if (bEditCell || nProgressCount > 100)
+    if (bFlush || nProgressCount > 100)
     {
         GetProgressBarHelper()->Increment(nProgressCount);
         nProgressCount = 0;
diff --git a/sc/source/filter/xml/xmlexprt.hxx b/sc/source/filter/xml/xmlexprt.hxx
index 4276e8e..a3b9905 100644
--- a/sc/source/filter/xml/xmlexprt.hxx
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@ -220,7 +220,7 @@ class ScXMLExport : public SvXMLExport
         const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xRowProperties,
         const OUString* pOldName, sal_Int32& rIndex );
 
-    void IncrementProgressBar(bool bEditCell, sal_Int32 nInc = 1);
+    void IncrementProgressBar(bool bFlush, sal_Int32 nInc = 1);
 
     void CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd );
 
commit d5d96b15551fb685a99a4ee4217a152e00bc0dbf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Sun Aug 25 14:38:30 2013 -0400

    fdo#60740: Export multi-line formula results to ods without UNO API.
    
    Change-Id: I69391a9d2ffb0afae7f40c8449196c986375db3f

diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 985aebe..c8a7414 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -310,6 +310,7 @@ public:
     void SetResultToken( const formula::FormulaToken* pToken );
 
     double GetResultDouble() const;
+    OUString GetResultString() const;
 
     void            SetErrCode( sal_uInt16 n );
     bool IsHyperLinkCell() const;
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index a7491a2..32238cd 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1705,6 +1705,11 @@ double ScFormulaCell::GetResultDouble() const
     return aResult.GetDouble();
 }
 
+OUString ScFormulaCell::GetResultString() const
+{
+    return aResult.GetString();
+}
+
 void ScFormulaCell::SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL )
 {
     aResult.SetMatrix(nCols, nRows, pMat, pUL);
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 10da5ff..42cac6d 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -3352,9 +3352,7 @@ void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount)
         else if (aCell.nType == table::CellContentType_FORMULA && IsMultiLineFormulaCell(aCell))
         {
             bEditCell = true;
-            uno::Reference<text::XText> xText(xCurrentTableCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row), uno::UNO_QUERY);
-            if ( xText.is())
-                GetTextParagraphExport()->exportText(xText, false, false);
+            WriteMultiLineFormulaResult(aCell.maBaseCell.mpFormula);
         }
         else
         {
@@ -3404,6 +3402,42 @@ void ScXMLExport::WriteEditCell(const EditTextObject* pText)
     flushParagraph(*this, aParaTexts[nCurPara], xMapper, xStylePool, rAttrMap, itPara, itSecEnd);
 }
 
+void ScXMLExport::WriteMultiLineFormulaResult(const ScFormulaCell* pCell)
+{
+    OUString aElemName = GetNamespaceMap().GetQNameByKey(XML_NAMESPACE_TEXT, GetXMLToken(XML_P));
+
+    OUString aResStr = pCell->GetResultString();
+    const sal_Unicode* p = aResStr.getStr();
+    const sal_Unicode* pEnd = p + static_cast<size_t>(aResStr.getLength());
+    const sal_Unicode* pPara = p; // paragraph head.
+    for (; p != pEnd; ++p)
+    {
+        if (*p != '\n')
+            continue;
+
+        // flush the paragraph.
+        OUString aContent;
+        if (*pPara == '\n')
+            ++pPara;
+        if (p > pPara)
+            aContent = OUString(pPara, p-pPara);
+
+        SvXMLElementExport aElem(*this, aElemName, false, false);
+        Characters(aContent);
+
+        pPara = p;
+    }
+
+    OUString aContent;
+    if (*pPara == '\n')
+        ++pPara;
+    if (pEnd > pPara)
+        aContent = OUString(pPara, pEnd-pPara);
+
+    SvXMLElementExport aElem(*this, aElemName, false, false);
+    Characters(aContent);
+}
+
 void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, awt::Point* pPoint)
 {
     uno::Reference < beans::XPropertySet > xShapeProps ( xShape, uno::UNO_QUERY );
diff --git a/sc/source/filter/xml/xmlexprt.hxx b/sc/source/filter/xml/xmlexprt.hxx
index 7a52297..4276e8e 100644
--- a/sc/source/filter/xml/xmlexprt.hxx
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@ -61,6 +61,7 @@ class ScXMLCachedRowAttrAccess;
 class ScRangeName;
 class ScXMLEditAttributeMap;
 class EditTextObject;
+class ScFormulaCell;
 
 typedef std::vector< com::sun::star::uno::Reference < com::sun::star::drawing::XShapes > > ScMyXShapesVec;
 
@@ -180,6 +181,7 @@ class ScXMLExport : public SvXMLExport
     void WriteTable(sal_Int32 nTable, const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet>& xTable);
     void WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount);
     void WriteEditCell(const EditTextObject* pText);
+    void WriteMultiLineFormulaResult(const ScFormulaCell* pCell);
     void WriteAreaLink(const ScMyCell& rMyCell);
     void WriteAnnotation(ScMyCell& rMyCell);
     void WriteDetective(const ScMyCell& rMyCell);
commit a8bf709911f84492624d8ebb12cb0d92bc2ee730
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Sun Aug 25 13:45:55 2013 -0400

    fdo#60740: Export cell field items without using UNO API.
    
    Change-Id: If4c11e962f7fc66087b751a582ad026f445863dc

diff --git a/sc/inc/editutil.hxx b/sc/inc/editutil.hxx
index 34ffd34..bf296c0 100644
--- a/sc/inc/editutil.hxx
+++ b/sc/inc/editutil.hxx
@@ -77,6 +77,9 @@ public:
 
     static EditTextObject* Clone( const EditTextObject& rSrc, ScDocument& rDestDoc );
 
+    static OUString GetCellFieldValue(
+        const SvxFieldData& rFieldData, const ScDocument* pDoc, Color** ppTextColor );
+
 public:
                 ScEditUtil( ScDocument* pDocument, SCCOL nX, SCROW nY, SCTAB nZ,
                             const Point& rScrPosPixel,
diff --git a/sc/source/core/tool/editutil.cxx b/sc/source/core/tool/editutil.cxx
index 0a0a057..c963243 100644
--- a/sc/source/core/tool/editutil.cxx
+++ b/sc/source/core/tool/editutil.cxx
@@ -195,6 +195,93 @@ EditTextObject* ScEditUtil::Clone( const EditTextObject& rObj, ScDocument& rDest
     return pNew;
 }
 
+OUString ScEditUtil::GetCellFieldValue(
+    const SvxFieldData& rFieldData, const ScDocument* pDoc, Color** ppTextColor )
+{
+    OUString aRet;
+    switch (rFieldData.GetClassId())
+    {
+        case text::textfield::Type::URL:
+        {
+            const SvxURLField& rField = static_cast<const SvxURLField&>(rFieldData);
+            OUString aURL = rField.GetURL();
+
+            switch (rField.GetFormat())
+            {
+                case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
+                case SVXURLFORMAT_REPR:
+                    aRet = rField.GetRepresentation();
+                break;
+                case SVXURLFORMAT_URL:
+                    aRet = aURL;
+                break;
+                default:
+                    ;
+            }
+
+            svtools::ColorConfigEntry eEntry =
+                INetURLHistory::GetOrCreate()->QueryUrl(aURL) ? svtools::LINKSVISITED : svtools::LINKS;
+
+            if (ppTextColor)
+                *ppTextColor = new Color( SC_MOD()->GetColorConfig().GetColorValue(eEntry).nColor );
+        }
+        break;
+        case text::textfield::Type::EXTENDED_TIME:
+        {
+            const SvxExtTimeField& rField = static_cast<const SvxExtTimeField&>(rFieldData);
+            if (pDoc)
+                aRet = rField.GetFormatted(*pDoc->GetFormatTable(), ScGlobal::eLnge);
+            else
+            {
+                /* TODO: quite expensive, we could have a global formatter? */
+                SvNumberFormatter aFormatter( comphelper::getProcessComponentContext(), ScGlobal::eLnge );
+                aRet = rField.GetFormatted(aFormatter, ScGlobal::eLnge);
+            }
+        }
+        break;
+        case text::textfield::Type::DATE:
+        {
+            Date aDate(Date::SYSTEM);
+            aRet = ScGlobal::pLocaleData->getDate(aDate);
+        }
+        break;
+        case text::textfield::Type::DOCINFO_TITLE:
+        {
+            if (pDoc)
+            {
+                SfxObjectShell* pDocShell = pDoc->GetDocumentShell();
+                if (pDocShell)
+                {
+                    aRet = pDocShell->getDocProperties()->getTitle();
+                    if (aRet.isEmpty())
+                        aRet = pDocShell->GetTitle();
+                }
+            }
+            if (aRet.isEmpty())
+                aRet = "?";
+        }
+        break;
+        case text::textfield::Type::TABLE:
+        {
+            const SvxTableField& rField = static_cast<const SvxTableField&>(rFieldData);
+            SCTAB nTab = rField.GetTab();
+            OUString aName;
+            if (pDoc && pDoc->GetName(nTab, aName))
+                aRet = aName;
+            else
+                aRet = "?";
+        }
+        break;
+        default:
+            aRet = "?";
+    }
+
+    if (aRet.isEmpty())        // leer ist baeh
+        aRet = " ";         // Space ist Default der Editengine
+
+    return aRet;
+}
+
 //------------------------------------------------------------------------
 
 Rectangle ScEditUtil::GetEditArea( const ScPatternAttr* pPattern, sal_Bool bForceToTop )
@@ -818,86 +905,7 @@ OUString ScFieldEditEngine::CalcFieldValue( const SvxFieldItem& rField,
     if (!pFieldData)
         return OUString(" ");
 
-    sal_uInt16 nClsId = pFieldData->GetClassId();
-    switch (nClsId)
-    {
-        case text::textfield::Type::URL:
-        {
-            const SvxURLField* pField = static_cast<const SvxURLField*>(pFieldData);
-            OUString aURL = pField->GetURL();
-
-            switch (pField->GetFormat())
-            {
-                case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
-                case SVXURLFORMAT_REPR:
-                    aRet = pField->GetRepresentation();
-                break;
-                case SVXURLFORMAT_URL:
-                    aRet = aURL;
-                break;
-                default:
-                    ;
-            }
-
-            svtools::ColorConfigEntry eEntry =
-                INetURLHistory::GetOrCreate()->QueryUrl(String(aURL)) ? svtools::LINKSVISITED : svtools::LINKS;
-            rTxtColor = new Color( SC_MOD()->GetColorConfig().GetColorValue(eEntry).nColor );
-        }
-        break;
-        case text::textfield::Type::EXTENDED_TIME:
-        {
-            const SvxExtTimeField* pField = static_cast<const SvxExtTimeField*>(pFieldData);
-            if (mpDoc)
-                aRet = pField->GetFormatted(*mpDoc->GetFormatTable(), ScGlobal::eLnge);
-            else
-            {
-                /* TODO: quite expensive, we could have a global formatter? */
-                SvNumberFormatter aFormatter( comphelper::getProcessComponentContext(), ScGlobal::eLnge );
-                aRet = pField->GetFormatted( aFormatter, ScGlobal::eLnge);
-            }
-        }
-        break;
-        case text::textfield::Type::DATE:
-        {
-            Date aDate(Date::SYSTEM);
-            aRet = ScGlobal::pLocaleData->getDate(aDate);
-        }
-        break;
-        case text::textfield::Type::DOCINFO_TITLE:
-        {
-            if (mpDoc)
-            {
-                SfxObjectShell* pDocShell = mpDoc->GetDocumentShell();
-                if (pDocShell)
-                {
-                    aRet = pDocShell->getDocProperties()->getTitle();
-                    if (aRet.isEmpty())
-                        aRet = pDocShell->GetTitle();
-                }
-            }
-            if (aRet.isEmpty())
-                aRet = "?";
-        }
-        break;
-        case text::textfield::Type::TABLE:
-        {
-            const SvxTableField* pField = static_cast<const SvxTableField*>(pFieldData);
-            SCTAB nTab = pField->GetTab();
-            OUString aName;
-            if (mpDoc && mpDoc->GetName(nTab, aName))
-                aRet = aName;
-            else
-                aRet = "?";
-        }
-        break;
-        default:
-            aRet = "?";
-    }
-
-    if (aRet.isEmpty())        // leer ist baeh
-        aRet = " ";         // Space ist Default der Editengine
-
-    return aRet;
+    return ScEditUtil::GetCellFieldValue(*pFieldData, mpDoc, &rTxtColor);
 }
 
 void ScFieldEditEngine::FieldClicked( const SvxFieldItem& rField, sal_Int32, sal_uInt16 )
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 8e07ed7..10da5ff 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -17,8 +17,6 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <editeng/eeitem.hxx>
-
 #include "xmlexprt.hxx"
 #include "XMLConverter.hxx"
 #include "xmlstyle.hxx"
@@ -89,6 +87,8 @@
 #include "editeng/wghtitem.hxx"
 #include "editeng/wrlmitem.hxx"
 #include "editeng/xmlcnitm.hxx"
+#include "editeng/flditem.hxx"
+#include "editeng/eeitem.hxx"
 #include <xmloff/xmlerror.hxx>
 #include <xmloff/XMLEventExport.hxx>
 
@@ -151,6 +151,7 @@
 
 #include <vector>
 #include <vbahelper/vbaaccesshelper.hxx>
+#include <boost/scoped_ptr.hpp>
 
 //! not found in unonames.hxx
 #define SC_LAYERID "LayerID"
@@ -1113,16 +1114,23 @@ void ScXMLExport::ExportExternalRefCacheStyles()
 
 namespace {
 
-void toXMLPropertyStates(
+const SvxFieldData* toXMLPropertyStates(
     std::vector<XMLPropertyState>& rPropStates, const std::vector<const SfxPoolItem*>& rSecAttrs,
     const UniReference<XMLPropertySetMapper>& xMapper, const ScXMLEditAttributeMap& rAttrMap )
 {
+    const SvxFieldData* pField = NULL;
     sal_Int32 nEntryCount = xMapper->GetEntryCount();
     rPropStates.reserve(rSecAttrs.size());
     std::vector<const SfxPoolItem*>::const_iterator it = rSecAttrs.begin(), itEnd = rSecAttrs.end();
     for (; it != itEnd; ++it)
     {
         const SfxPoolItem* p = *it;
+        if (p->Which() == EE_FEATURE_FIELD)
+        {
+            pField = static_cast<const SvxFieldItem*>(p)->GetField();
+            continue;
+        }
+
         const ScXMLEditAttributeMap::Entry* pEntry = rAttrMap.getEntryByItemID(p->Which());
         if (!pEntry)
             continue;
@@ -1317,6 +1325,8 @@ void toXMLPropertyStates(
                 continue;
         }
     }
+
+    return pField;
 }
 
 }
@@ -3061,6 +3071,94 @@ void ScXMLExport::WriteTable(sal_Int32 nTable, const Reference<sheet::XSpreadshe
 
 namespace {
 
+void writeContent(
+    ScXMLExport& rExport, const OUString& rStyleName, const OUString& rContent, const SvxFieldData* pField )
+{
+    boost::scoped_ptr<SvXMLElementExport> pElem;
+    if (!rStyleName.isEmpty())
+    {
+        // Formatted section with automatic style.
+        rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, rStyleName);
+        OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
+            XML_NAMESPACE_TEXT, GetXMLToken(XML_SPAN));
+        pElem.reset(new SvXMLElementExport(rExport, aElemName, false, false));
+    }
+
+    if (pField)
+    {
+        // Write an field item.
+        OUString aFieldVal = ScEditUtil::GetCellFieldValue(*pField, rExport.GetDocument(), NULL);
+        switch (pField->GetClassId())
+        {
+            case text::textfield::Type::URL:
+            {
+                // <text:a xlink:href="url" xlink:type="simple">value</text:a>
+
+                OUString aURL = static_cast<const SvxURLField*>(pField)->GetURL();
+                rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aURL);
+                rExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, "simple");
+
+                OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
+                    XML_NAMESPACE_TEXT, GetXMLToken(XML_A));
+                SvXMLElementExport aElem(rExport, aElemName, false, false);
+                rExport.Characters(aFieldVal);
+            }
+            break;
+            case text::textfield::Type::DATE:
+            {
+                // <text:date style:data-style-name="N2" text:date-value="YYYY-MM-DD">value</text:date>
+
+                Date aDate(Date::SYSTEM);
+                OUStringBuffer aBuf;
+                sal_Int32 nVal = aDate.GetYear();
+                aBuf.append(nVal);
+                aBuf.append(sal_Unicode('-'));
+                nVal = aDate.GetMonth();
+                if (nVal < 10)
+                    aBuf.append(sal_Unicode('0'));
+                aBuf.append(nVal);
+                aBuf.append(sal_Unicode('-'));
+                nVal = aDate.GetDay();
+                if (nVal < 10)
+                    aBuf.append(sal_Unicode('0'));
+                aBuf.append(nVal);
+                rExport.AddAttribute(XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, "N2");
+                rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_DATE_VALUE, aBuf.makeStringAndClear());
+
+                OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
+                    XML_NAMESPACE_TEXT, GetXMLToken(XML_DATE));
+                SvXMLElementExport aElem(rExport, aElemName, false, false);
+                rExport.Characters(aFieldVal);
+            }
+            break;
+            case text::textfield::Type::DOCINFO_TITLE:
+            {
+                // <text:title>value</text:title>
+
+                OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
+                    XML_NAMESPACE_TEXT, GetXMLToken(XML_TITLE));
+                SvXMLElementExport aElem(rExport, aElemName, false, false);
+                rExport.Characters(aFieldVal);
+            }
+            break;
+            case text::textfield::Type::TABLE:
+            {
+                // <text:sheet-name>value</text:sheet-name>
+
+                OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
+                    XML_NAMESPACE_TEXT, GetXMLToken(XML_SHEET_NAME));
+                SvXMLElementExport aElem(rExport, aElemName, false, false);
+                rExport.Characters(aFieldVal);
+            }
+            break;
+            default:
+                rExport.Characters(aFieldVal);
+        }
+    }
+    else
+        rExport.Characters(rContent);
+}
+
 void flushParagraph(
     ScXMLExport& rExport, const OUString& rParaText,
     UniReference<XMLPropertySetMapper> xMapper, UniReference<SvXMLAutoStylePoolP> xStylePool,
@@ -3083,23 +3181,9 @@ void flushParagraph(
         OUString aContent(pBeg, pEnd-pBeg);
 
         std::vector<XMLPropertyState> aPropStates;
-        toXMLPropertyStates(aPropStates, rSec.maAttributes, xMapper, rAttrMap);
+        const SvxFieldData* pField = toXMLPropertyStates(aPropStates, rSec.maAttributes, xMapper, rAttrMap);
         OUString aStyleName = xStylePool->Find(XML_STYLE_FAMILY_TEXT_TEXT, OUString(), aPropStates);
-
-        if (aStyleName.isEmpty())
-        {
-            // Unformatted section.
-            rExport.Characters(aContent);
-        }
-        else
-        {
-            // Formatted section with automatic style.
-            rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, aStyleName);
-            aElemName = rExport.GetNamespaceMap().GetQNameByKey(
-                XML_NAMESPACE_TEXT, GetXMLToken(XML_SPAN));
-            SvXMLElementExport aElem(rExport, aElemName, false, false);
-            rExport.Characters(aContent);
-        }
+        writeContent(rExport, aStyleName, aContent, pField);
     }
 }
 
commit d81b56c7f679477fed471f8150e1b95e6902e249
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Sun Aug 25 00:07:45 2013 -0400

    fdo#60740: Handle empty paragraphs correctly.
    
    Change-Id: I47d4f60daec82d2b6a4b5e8f20b8cb6484c55057

diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx
index ac6b809..8f3b9a0 100644
--- a/editeng/source/editeng/editobj.cxx
+++ b/editeng/source/editeng/editobj.cxx
@@ -902,6 +902,13 @@ void EditTextObjectImpl::GetAllSectionAttributes( std::vector<editeng::SectionAt
     {
         size_t nPara = distance(aParaBorders.begin(), it);
         const SectionBordersType& rBorders = *it;
+        if (rBorders.size() == 1 && rBorders[0] == 0)
+        {
+            // Empty paragraph. Push an empty section.
+            aAttrs.push_back(editeng::SectionAttribute(nPara, 0, 0));
+            continue;
+        }
+
         SectionBordersType::const_iterator itBorder = rBorders.begin(), itBorderEnd = rBorders.end();
         size_t nPrev = *itBorder;
         size_t nCur;
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 1f0e252..8e07ed7 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -3067,9 +3067,6 @@ void flushParagraph(
     const ScXMLEditAttributeMap& rAttrMap,
     std::vector<editeng::SectionAttribute>::const_iterator it, std::vector<editeng::SectionAttribute>::const_iterator itEnd )
 {
-    if (it == itEnd)
-        return;
-
     OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
         XML_NAMESPACE_TEXT, GetXMLToken(XML_P));
     SvXMLElementExport aElemP(rExport, aElemName, false, false);
commit 882bee5ede38b6ed4e1ec870d835546868c6586d
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Sat Aug 24 23:24:13 2013 -0400

    fdo#60740: Export edit cells to ods without using UNO API.
    
    Change-Id: If571d99060f87fd00e215fd93da1654fdcb50197

diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index b94ccc2..1f0e252 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -3059,6 +3059,55 @@ void ScXMLExport::WriteTable(sal_Int32 nTable, const Reference<sheet::XSpreadshe
     }
 }
 
+namespace {
+
+void flushParagraph(
+    ScXMLExport& rExport, const OUString& rParaText,
+    UniReference<XMLPropertySetMapper> xMapper, UniReference<SvXMLAutoStylePoolP> xStylePool,
+    const ScXMLEditAttributeMap& rAttrMap,
+    std::vector<editeng::SectionAttribute>::const_iterator it, std::vector<editeng::SectionAttribute>::const_iterator itEnd )
+{
+    if (it == itEnd)
+        return;
+
+    OUString aElemName = rExport.GetNamespaceMap().GetQNameByKey(
+        XML_NAMESPACE_TEXT, GetXMLToken(XML_P));
+    SvXMLElementExport aElemP(rExport, aElemName, false, false);
+
+    for (; it != itEnd; ++it)
+    {
+        const editeng::SectionAttribute& rSec = *it;
+
+        const sal_Unicode* pBeg = rParaText.getStr();
+        std::advance(pBeg, rSec.mnStart);
+        const sal_Unicode* pEnd = pBeg;
+        std::advance(pEnd, rSec.mnEnd-rSec.mnStart);
+
+        OUString aContent(pBeg, pEnd-pBeg);
+
+        std::vector<XMLPropertyState> aPropStates;
+        toXMLPropertyStates(aPropStates, rSec.maAttributes, xMapper, rAttrMap);
+        OUString aStyleName = xStylePool->Find(XML_STYLE_FAMILY_TEXT_TEXT, OUString(), aPropStates);
+
+        if (aStyleName.isEmpty())
+        {
+            // Unformatted section.
+            rExport.Characters(aContent);
+        }
+        else
+        {
+            // Formatted section with automatic style.
+            rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, aStyleName);
+            aElemName = rExport.GetNamespaceMap().GetQNameByKey(
+                XML_NAMESPACE_TEXT, GetXMLToken(XML_SPAN));
+            SvXMLElementExport aElem(rExport, aElemName, false, false);
+            rExport.Characters(aContent);
+        }
+    }
+}
+
+}
+
 void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount)
 {
     // nEqualCellCount is the number of additional cells
@@ -3214,12 +3263,10 @@ void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount)
 
     if (!bIsEmpty)
     {
-        if (aCell.nType == table::CellContentType_TEXT && IsEditCell(aCell))
+        if (aCell.nType == table::CellContentType_TEXT && aCell.maBaseCell.meType == CELLTYPE_EDIT)
         {
             bEditCell = true;
-            uno::Reference<text::XText> xText(xCurrentTableCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row), uno::UNO_QUERY);
-            if ( xText.is())
-                GetTextParagraphExport()->exportText(xText, false, false);
+            WriteEditCell(aCell.maBaseCell.mpEditText);
         }
         else if (aCell.nType == table::CellContentType_FORMULA && IsMultiLineFormulaCell(aCell))
         {
@@ -3241,6 +3288,41 @@ void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount)
         IncrementProgressBar(bEditCell);
 }
 
+void ScXMLExport::WriteEditCell(const EditTextObject* pText)
+{
+    UniReference<XMLPropertySetMapper> xMapper = GetTextParagraphExport()->GetTextPropMapper()->getPropertySetMapper();
+    UniReference<SvXMLAutoStylePoolP> xStylePool = GetAutoStylePool();
+    const ScXMLEditAttributeMap& rAttrMap = GetEditAttributeMap();
+
+    // Get raw paragraph texts first.
+    std::vector<OUString> aParaTexts;
+    sal_Int32 nParaCount = pText->GetParagraphCount();
+    aParaTexts.reserve(nParaCount);
+    for (sal_Int32 i = 0; i < nParaCount; ++i)
+        aParaTexts.push_back(pText->GetText(i));
+
+    // Get all section data and iterate through them.
+    std::vector<editeng::SectionAttribute> aAttrs;
+    pText->GetAllSectionAttributes(aAttrs);
+    std::vector<editeng::SectionAttribute>::const_iterator itSec = aAttrs.begin(), itSecEnd = aAttrs.end();
+    std::vector<editeng::SectionAttribute>::const_iterator itPara = itSec;
+    size_t nCurPara = 0; // current paragraph
+    for (; itSec != itSecEnd; ++itSec)
+    {
+        const editeng::SectionAttribute& rSec = *itSec;
+        if (nCurPara == rSec.mnParagraph)
+            // Still in the same paragraph.
+            continue;
+
+        // Start of a new paragraph. Flush the old paragraph.
+        flushParagraph(*this, aParaTexts[nCurPara], xMapper, xStylePool, rAttrMap, itPara, itSec);
+        nCurPara = rSec.mnParagraph;
+        itPara = itSec;
+    }
+
+    flushParagraph(*this, aParaTexts[nCurPara], xMapper, xStylePool, rAttrMap, itPara, itSecEnd);
+}
+
 void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, awt::Point* pPoint)
 {
     uno::Reference < beans::XPropertySet > xShapeProps ( xShape, uno::UNO_QUERY );
diff --git a/sc/source/filter/xml/xmlexprt.hxx b/sc/source/filter/xml/xmlexprt.hxx
index 3f01dfe..7a52297 100644
--- a/sc/source/filter/xml/xmlexprt.hxx
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@ -60,6 +60,7 @@ class ScAddress;
 class ScXMLCachedRowAttrAccess;
 class ScRangeName;
 class ScXMLEditAttributeMap;
+class EditTextObject;
 
 typedef std::vector< com::sun::star::uno::Reference < com::sun::star::drawing::XShapes > > ScMyXShapesVec;
 
@@ -178,6 +179,7 @@ class ScXMLExport : public SvXMLExport
 
     void WriteTable(sal_Int32 nTable, const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet>& xTable);
     void WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount);
+    void WriteEditCell(const EditTextObject* pText);
     void WriteAreaLink(const ScMyCell& rMyCell);
     void WriteAnnotation(ScMyCell& rMyCell);
     void WriteDetective(const ScMyCell& rMyCell);
commit 0d57434180db6c8eda8c5b9b704f8a1c18b371df
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Sat Aug 24 22:57:48 2013 -0400

    Create sections for unformatted paragraphs too.
    
    Change-Id: Id3486cf7faf0c03f2ce9c72f31d564d5149e5b48

diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx
index c7db485..ac6b809 100644
--- a/editeng/source/editeng/editobj.cxx
+++ b/editeng/source/editeng/editobj.cxx
@@ -860,35 +860,25 @@ public:
 void EditTextObjectImpl::GetAllSectionAttributes( std::vector<editeng::SectionAttribute>& rAttrs ) const
 {
     typedef std::vector<size_t> SectionBordersType;
-    typedef std::map<size_t, SectionBordersType> ParagraphsType;
-    ParagraphsType aParaBorders;
+    typedef std::vector<SectionBordersType> ParagraphsType;
+    ParagraphsType aParaBorders(aContents.size());
 
     // First pass: determine section borders for each paragraph.
     for (size_t nPara = 0; nPara < aContents.size(); ++nPara)
     {
         const ContentInfo& rC = aContents[nPara];
+        SectionBordersType& rBorders = aParaBorders[nPara];
+        rBorders.push_back(0);
+        rBorders.push_back(rC.GetText().Len());
         for (size_t nAttr = 0; nAttr < rC.aAttribs.size(); ++nAttr)
         {
             const XEditAttribute& rAttr = rC.aAttribs[nAttr];
             const SfxPoolItem* pItem = rAttr.GetItem();
-            if (!pItem || pItem->Which() == EE_FEATURE_FIELD)
+            if (!pItem)
                 continue;
 
-            ParagraphsType::iterator it = aParaBorders.lower_bound(nPara);
-            SectionBordersType* pBorders = NULL;
-            if (it != aParaBorders.end() && !aParaBorders.key_comp()(nPara, it->first))
-            {
-                // Container for this paragraph already exists.
-                pBorders = &it->second;
-            }
-            else
-            {
-                it = aParaBorders.insert(it, ParagraphsType::value_type(nPara, SectionBordersType()));
-                pBorders = &it->second;
-            }
-
-            pBorders->push_back(rAttr.GetStart());
-            pBorders->push_back(rAttr.GetEnd());
+            rBorders.push_back(rAttr.GetStart());
+            rBorders.push_back(rAttr.GetEnd());
         }
     }
 
@@ -896,7 +886,7 @@ void EditTextObjectImpl::GetAllSectionAttributes( std::vector<editeng::SectionAt
     ParagraphsType::iterator it = aParaBorders.begin(), itEnd = aParaBorders.end();
     for (; it != itEnd; ++it)
     {
-        SectionBordersType& rBorders = it->second;
+        SectionBordersType& rBorders = *it;
         std::sort(rBorders.begin(), rBorders.end());
         SectionBordersType::iterator itUniqueEnd = std::unique(rBorders.begin(), rBorders.end());
         rBorders.erase(itUniqueEnd, rBorders.end());
@@ -910,11 +900,8 @@ void EditTextObjectImpl::GetAllSectionAttributes( std::vector<editeng::SectionAt
     it = aParaBorders.begin();
     for (; it != itEnd; ++it)
     {
-        size_t nPara = it->first;
-        const SectionBordersType& rBorders = it->second;
-        if (rBorders.empty())
-            continue;
-
+        size_t nPara = distance(aParaBorders.begin(), it);
+        const SectionBordersType& rBorders = *it;
         SectionBordersType::const_iterator itBorder = rBorders.begin(), itBorderEnd = rBorders.end();
         size_t nPrev = *itBorder;
         size_t nCur;
@@ -933,7 +920,7 @@ void EditTextObjectImpl::GetAllSectionAttributes( std::vector<editeng::SectionAt
     std::vector<editeng::SectionAttribute>::iterator itAttr = aAttrs.begin();
     for (; it != itEnd; ++it)
     {
-        size_t nPara = it->first;
+        size_t nPara = distance(aParaBorders.begin(), it);
         const ContentInfo& rC = aContents[nPara];
         if (itAttr->mnParagraph != nPara)
             // Find the first container for the current paragraph.


More information about the Libreoffice-commits mailing list