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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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. _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
