# HG changeset patch
# User Michael Stahl <mst@openoffice.org>
# Date 1288022122 -7200
# Node ID d80c9a92e571b0a2eee1c0f0479c332649c5e9ee
# Parent  3b79c4a0ec8d9f07212819c60ca4ebccc0e75c8d
rtftok01: nested sprms...

diff --git a/writerfilter/source/rtftok/RTFDestination.hxx b/writerfilter/source/rtftok/RTFDestination.hxx
--- a/writerfilter/source/rtftok/RTFDestination.hxx
+++ b/writerfilter/source/rtftok/RTFDestination.hxx
@@ -315,15 +315,19 @@
 fprintf(stderr, "RTFDestination::HandleStringU: ignoring stringU\n");
     }
 
-    void SetEncodingToFont(const sal_Int32 i);
-    sal_uInt32 GetColorTableEntry(const sal_Int32 i);
+    void SetEncodingToFont(sal_Int32 const i);
+    sal_uInt32 GetColorTableEntry(sal_Int32 const i);
     void HandleSymbol(sal_Unicode const c);
     void SetAttribute(Id const id, RTFValue::Pointer_t const& pValue);
     void SetCharacterSprm(Id const id, RTFValue::Pointer_t const& pValue);
     void SetParagraphSprm(Id const id, RTFValue::Pointer_t const& pValue);
     void SetSectionSprm(Id const id, RTFValue::Pointer_t const& pValue);
     void SetTableRowSprm(Id const id, RTFValue::Pointer_t const& pValue);
+    void SetTableRowNestedSprm(Id const parent, Id const id,
+            RTFValue::Pointer_t const& pValue);
     void SetTableCellSprm(Id const id, RTFValue::Pointer_t const& pValue);
+    void SetTableCellNestedSprm(Id const parent, Id const id,
+            RTFValue::Pointer_t const& pValue);
     void ResetCharacterProperties();
     void ResetParagraphProperties();
     void ResetSectionProperties();
diff --git a/writerfilter/source/rtftok/RTFDocumentImpl.cxx b/writerfilter/source/rtftok/RTFDocumentImpl.cxx
--- a/writerfilter/source/rtftok/RTFDocumentImpl.cxx
+++ b/writerfilter/source/rtftok/RTFDocumentImpl.cxx
@@ -144,6 +144,79 @@
 
 
 
+/** Value class for Sprms.
+ */
+class RTFValueSprms
+    : public RTFValue
+{
+
+public:
+    typedef ::std::map<Id, RTFValue::Pointer_t > Attributes_t;
+    explicit RTFValueSprms()
+        : m_Value()
+    { }
+    explicit RTFValueSprms(Attributes_t const& rValue)
+        : m_Value(rValue)
+    { }
+    virtual ~RTFValueSprms() { }
+    virtual RTFValue * Clone() { return new RTFValueSprms(m_Value); }
+
+    // don't throw exceptions, just return null values
+    virtual int getInt() const
+    {
+        return 0;
+    }
+    virtual ::rtl::OUString getString() const
+    {
+        return ::rtl::OUString();
+    }
+    virtual uno::Any getAny() const
+    {
+        uno::Any ret;
+//        ret <<= m_Value;
+        return ret;
+    }
+    virtual writerfilter::Reference<Properties>::Pointer_t getProperties()
+    {
+        RTFRefProperties::Attributes_t const dummy;
+        writerfilter::Reference<Properties>::Pointer_t pRet(
+                new RTFRefProperties(dummy, m_Value));
+        return writerfilter::Reference<Properties>::Pointer_t();
+    }
+    virtual writerfilter::Reference<Stream>::Pointer_t getStream()
+    {
+        return writerfilter::Reference<Stream>::Pointer_t();
+    }
+    virtual writerfilter::Reference<BinaryObj>::Pointer_t getBinary()
+    {
+        return writerfilter::Reference<BinaryObj>::Pointer_t();
+    }
+    virtual ::std::string toString() const
+    {
+        ::std::string ret("[");
+        for (Attributes_t::const_iterator iter = m_Value.begin();
+                iter < m_Value.end(); ++iter)
+        {
+            ret += iter->first;
+            ret += ::std::string(" -> ");
+            ret += iter->second->toString();
+            ret += ::std::string(",");
+        }
+        ret += ::std::string("]");
+        return ret;
+    }
+
+    void SetSprm(Id const id, RTFValue::Pointer_t const& pValue)
+    {
+        m_Value[id] = pValue;
+    }
+
+private:
+    Attributes_t m_Value;
+};
+
+
+
 class RTFInputStream
     : public RTFInputSource
 {
@@ -582,6 +655,28 @@
     GetHandler().SetTableRowSprm(id, pValue);
 }
 
+static RTFValue::Pointer_t
+lcl_SetNestedSprm(RTFGroup::Attributes_t rSprms, Id const parent,
+        Id const id, RTFValue::Pointer_t const& pValue)
+{
+    RTFGroup::Attributes_t::iterator const iter(rSprms.find(parent));
+    RTFValue::Pointer_t const pParent( (iter != rSprms.end())
+        ?   iter->second
+        :   RTFValue::Pointer_t(new RTFValueSprms()) );
+    dynamic_cast<RTFValueSprms *>(pParent.get())->SetSprm(id, pValue);
+    return pParent;
+}
+
+void
+RTFDestination::SetTableRowNestedSprm(Id const parent, Id const id,
+        RTFValue::Pointer_t const& pValue)
+{
+    RTFGroup & rGroup( GetHandler().GetCurrentGroup() );
+    RTFValue::Pointer_t const pParent( lcl_SetNestedSprm(
+        rGroup.m_TableRowProperties.m_Sprms, parent, id, pValue) );
+    GetHandler().SetTableRowSprm(id, pParent);
+}
+
 void
 RTFDestination::SetTableCellSprm(Id const id, RTFValue::Pointer_t const& pValue)
 {
@@ -589,6 +684,16 @@
 }
 
 void
+RTFDestination::SetTableCellNestedSprm(Id const parent, Id const id,
+        RTFValue::Pointer_t const& pValue)
+{
+    RTFGroup & rGroup( GetHandler().GetCurrentGroup() );
+    RTFValue::Pointer_t const pParent( lcl_SetNestedSprm(
+        rGroup.m_TableCellProperties.m_Sprms, parent, id, pValue) );
+    GetHandler().SetTableCellSprm(id, pValue);
+}
+
+void
 RTFDestination::ResetCharacterProperties()
 {
     GetHandler().ResetCharacterProperties();
@@ -873,7 +978,7 @@
                     attrmap.insert(::std::make_pair(NS_rtf::LN_XSZFFN, pName));
                 }
 
-                RTFRefProperties::Attributes_t dummy;
+                RTFRefProperties::Attributes_t const dummy;
                 writerfilter::Reference<Properties>::Pointer_t const pProperties(
                         new RTFRefProperties(attrmap, dummy) );
                 m_Properties.insert(
diff --git a/writerfilter/source/rtftok/rtfactions.xml b/writerfilter/source/rtftok/rtfactions.xml
--- a/writerfilter/source/rtftok/rtfactions.xml
+++ b/writerfilter/source/rtftok/rtfactions.xml
@@ -634,17 +634,18 @@
     <!-- <ref name="trspofl"/> -->
     <!-- <ref name="trspofr"/> -->
     <!-- <ref name="trspoft"/> -->
-    <ref name="trwWidth" tokenid="ooxml:CT_TblPrBase_tblW"/>
-    <!-- <ref name="trftsWidth" tokenid="ooxml:CT_TblPrBase_tblW"/>
-    need a mapping here with trwWidth-->
+    <ref name="trwWidth"
+      parent="ooxml:CT_TblPrBase_tblW" tokenid="rtf:preferredWidth"/>
+    <ref name="trftsWidth"
+      parent="ooxml:CT_TblPrBase_tblW" tokenid="rtf:unit"/>
     <!-- <ref name="trwWidthB"/> -->
     <!-- <ref name="trftsWidthB"/> -->
     <!-- <ref name="trwWidthA"/> -->
     <!-- <ref name="trftsWidthA"/> -->
-    <ref name="tblind" tokenid="ooxml:CT_TblPrBase_tblInd"/>
-    <!-- <ref name="tblindtype" tokenid="ooxml:CT_TblPrBase_tblInd"/>
-    need a mapping here, and combine with tblind...
-    -->
+    <ref name="tblind"
+      parent="ooxml:CT_TblPrBase_tblInd" tokenid="rtf:trleft"/>
+    <ref name="tblindtype"
+      parent="ooxml:CT_TblPrBase_tblInd" tokenid="rtf:unit"/>
 
     <!-- ooxml::LN_CT_TblPrBase_shd: how does this work -->
     <!-- <ref name="trcbpat"/> -->
diff --git a/writerfilter/source/rtftok/rtfcontrols.xsl b/writerfilter/source/rtftok/rtfcontrols.xsl
--- a/writerfilter/source/rtftok/rtfcontrols.xsl
+++ b/writerfilter/source/rtftok/rtfcontrols.xsl
@@ -33,6 +33,27 @@
 
   <xsl:key name="names" match="//control|//destination|//flag|//toggle|//value|//symbol" use="@name"/>
 
+  <xsl:template name="token-to-enum">
+    <xsl:param name="token"/>
+    <xsl:choose>
+      <xsl:when test="starts-with($token, 'sprm:')">
+        <xsl:text>NS_sprm::LN_</xsl:text>
+        <xsl:value-of select="substring(@tokenid, 6)"/>
+      </xsl:when>
+      <xsl:when test="starts-with($token, 'rtf:')">
+        <xsl:text>NS_rtf::LN_</xsl:text>
+        <xsl:value-of select="substring(@tokenid, 5)"/>
+      </xsl:when>
+      <xsl:when test="starts-with($token, 'ooxml:')">
+        <xsl:text>NS_ooxml::LN_</xsl:text>
+        <xsl:value-of select="substring($token, 7)"/>
+      </xsl:when>
+      <xsl:when test="starts-with($token, '0x')">
+        <xsl:value-of select="@tokenid"/>
+      </xsl:when>
+    </xsl:choose>
+  </xsl:template>
+
   <xsl:template name="handle-case">
     <xsl:param name="kind"/>
     <xsl:variable name="name">
@@ -45,19 +66,9 @@
       </xsl:for-each>
     </xsl:variable>
     <xsl:variable name="token">
-      <xsl:choose>
-        <xsl:when test="starts-with(@tokenid, 'sprm:')">
-          <xsl:text>NS_sprm::LN_</xsl:text>
-          <xsl:value-of select="substring(@tokenid, 6)"/>
-        </xsl:when>
-        <xsl:when test="starts-with(@tokenid, 'ooxml:')">
-          <xsl:text>NS_ooxml::LN_</xsl:text>
-          <xsl:value-of select="substring(@tokenid, 7)"/>
-        </xsl:when>
-        <xsl:when test="starts-with(@tokenid, '0x')">
-          <xsl:value-of select="@tokenid"/>
-        </xsl:when>
-      </xsl:choose>
+      <xsl:call-template name="token-to-enum">
+        <xsl:with-param name="token" select="@tokenid"/>
+      </xsl:call-template>
     </xsl:variable>
     <xsl:text>case RTF_</xsl:text>
     <xsl:value-of select="@name"/>
@@ -122,6 +133,29 @@
         </xsl:otherwise>
       </xsl:choose>
       <xsl:choose>
+        <xsl:when test="@parent">
+          <xsl:variable name="parent">
+            <xsl:call-template name="token-to-enum">
+              <xsl:with-param name="token" select="@parent"/>
+            </xsl:call-template>
+          </xsl:variable>
+          <xsl:choose>
+            <xsl:when test="$kind='tablerow'">
+              <xsl:text>rDestination.SetTableRowNestedSprm(</xsl:text>
+            </xsl:when>
+            <xsl:when test="$kind='tablecell'">
+              <xsl:text>rDestination.SetTableCellNestedSprm(</xsl:text>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:text>UNKNOWN KIND: </xsl:text>
+              <xsl:value-of select="$kind"/>
+            </xsl:otherwise>
+          </xsl:choose>
+          <xsl:value-of select="$parent"/>
+          <xsl:text>, </xsl:text>
+          <xsl:value-of select="$token"/>
+          <xsl:text>, pValue);&#xA;</xsl:text>
+        </xsl:when>
         <xsl:when test="starts-with(@tokenid, 'sprm:') or starts-with(@tokenid, 'ooxml:') or starts-with(@tokenid, '0x')">
           <xsl:choose>
             <xsl:when test="$kind='character'">
