summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-02-08 19:43:22 -0500
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-02-11 22:33:33 -0500
commitfa23b694c1979254c9a045bcf51d281c29d80c8d (patch)
treefa2c6e2682139a01108494e0d1724b5dd616f8a0 /sc
parent96d89d9cc77105cb5cf864f4392554f9613d12cf (diff)
Import formatted spans correctly.
There are more format types to cover. I'm not done yet. Change-Id: I42fab04f65810733e5b25fbbc2c92df7e05c05cf
Diffstat (limited to 'sc')
-rw-r--r--sc/source/filter/xml/celltextparacontext.cxx37
-rw-r--r--sc/source/filter/xml/celltextparacontext.hxx3
-rw-r--r--sc/source/filter/xml/xmlcelli.cxx158
-rw-r--r--sc/source/filter/xml/xmlcelli.hxx22
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx17
-rw-r--r--sc/source/filter/xml/xmlimprt.hxx13
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)
{