[Libreoffice-commits] core.git: writerfilter/source

Eilidh McAdam eilidh.mcadam at itomig.de
Fri Dec 19 09:20:56 PST 2014


 writerfilter/source/dmapper/DomainMapper.cxx          |    4 
 writerfilter/source/dmapper/DomainMapper_Impl.cxx     |   76 ++++++++++++++++--
 writerfilter/source/dmapper/DomainMapper_Impl.hxx     |    7 +
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx |    9 ++
 writerfilter/source/ooxml/OOXMLFastContextHandler.hxx |    1 
 writerfilter/source/ooxml/OOXMLPropertySetImpl.cxx    |   20 ++++
 writerfilter/source/ooxml/OOXMLPropertySetImpl.hxx    |   14 +++
 writerfilter/source/ooxml/factoryimpl_ns.py           |    8 +
 writerfilter/source/ooxml/model.xml                   |    5 -
 9 files changed, 137 insertions(+), 7 deletions(-)

New commits:
commit 8826934016d60d0a4a1e824e3f1cff814d915515
Author: Eilidh McAdam <eilidh.mcadam at itomig.de>
Date:   Wed Dec 10 03:50:10 2014 +0000

    Support for docx import of fixed date and time fields.
    
    If a field is fixed, mark it as such and parse value to seed it.
    This is the other half of the docx filter improvement for fdo#59886.
    
    Reviewed on:
    	https://gerrit.libreoffice.org/13431
    
    Change-Id: Id00c454921cd386589e04b9572f4040898625a6f

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index ec5afab..2f0e43d 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2826,6 +2826,10 @@ void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len)
             switch(*data_)
             {
                 case 0x02: return; //footnote character
+                case 0x08: // Lock field if in field context
+                    if (m_pImpl->IsOpenField())
+                        m_pImpl->SetFieldLocked();
+                    return;
                 case 0x0c: //page break
                     m_pImpl->deferBreak(PAGE_BREAK);
                     return;
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index d080ae8..a3694bd 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -161,6 +161,7 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_xComponentContext( xContext ),
         m_bSetUserFieldContent( false ),
         m_bSetCitation( false ),
+        m_bSetDateValue( false ),
         m_bIsFirstSection( true ),
         m_bIsColumnBreakDeferred( false ),
         m_bIsPageBreakDeferred( false ),
@@ -2588,6 +2589,13 @@ bool DomainMapper_Impl::IsOpenField() const
     return !m_aFieldStack.empty();
 }
 
+// Mark top field context as containing a fixed field
+void DomainMapper_Impl::SetFieldLocked()
+{
+    if (IsOpenField())
+        m_aFieldStack.top()->SetFieldLocked();
+}
+
 HeaderFooterContext::HeaderFooterContext(bool bTextInserted)
     : m_bTextInserted(bTextInserted)
 {
@@ -2600,7 +2608,8 @@ bool HeaderFooterContext::getTextInserted()
 
 FieldContext::FieldContext(uno::Reference< text::XTextRange > const& xStart)
     : m_bFieldCommandCompleted(false)
-    ,m_xStartRange( xStart )
+    , m_xStartRange( xStart )
+    , m_bFieldLocked( false )
 {
     m_pProperties.reset(new PropertyMap());
 }
@@ -3399,6 +3408,7 @@ void DomainMapper_Impl::CloseFieldCommand()
     {
         m_bSetUserFieldContent = false;
         m_bSetCitation = false;
+        m_bSetDateValue = false;
         FieldConversionMap_t aFieldConversionMap = lcl_GetFieldConversion();
 
         try
@@ -3509,10 +3519,19 @@ void DomainMapper_Impl::CloseFieldCommand()
                     case FIELD_DATE:
                     if (xFieldProperties.is())
                     {
-                        //not fixed,
-                        xFieldProperties->setPropertyValue(
-                            rPropNameSupplier.GetName(PROP_IS_FIXED),
-                            uno::makeAny( false ));
+                        // Get field fixed property from the context handler
+                        if (pContext->IsFieldLocked())
+                        {
+                            xFieldProperties->setPropertyValue(
+                                rPropNameSupplier.GetName(PROP_IS_FIXED),
+                                uno::makeAny( true ));
+                            m_bSetDateValue = true;
+                        }
+                        else
+                            xFieldProperties->setPropertyValue(
+                                rPropNameSupplier.GetName(PROP_IS_FIXED),
+                                uno::makeAny( false ));
+
                         xFieldProperties->setPropertyValue(
                             rPropNameSupplier.GetName(PROP_IS_DATE),
                             uno::makeAny( true ));
@@ -3902,7 +3921,16 @@ void DomainMapper_Impl::CloseFieldCommand()
                     case FIELD_SYMBOL       : break;
                     case FIELD_TEMPLATE: break;
                     case FIELD_TIME         :
+                    {
+                        if (pContext->IsFieldLocked())
+                        {
+                            xFieldProperties->setPropertyValue(
+                                rPropNameSupplier.GetName(PROP_IS_FIXED),
+                                uno::makeAny( true ));
+                            m_bSetDateValue = true;
+                        }
                         SetNumberFormat( pContext->GetCommand(), xFieldProperties );
+                    }
                     break;
                     case FIELD_TITLE        :
                     {
@@ -4084,6 +4112,29 @@ void DomainMapper_Impl::AppendFieldResult(OUString const& rString)
     }
 }
 
+// Calculates css::DateTime based on ddddd.sssss since 1900-1-0
+::com::sun::star::util::DateTime lcl_dateTimeFromSerial(const double& dSerial)
+{
+    const sal_uInt32 secondsPerDay = 86400;
+    const sal_uInt16 secondsPerHour = 3600;
+
+    DateTime d(Date(30, 12, 1899));
+    d += (long)dSerial;
+
+    double frac = dSerial - (long)dSerial;
+    sal_uInt32 seconds = frac * secondsPerDay;
+
+    ::com::sun::star::util::DateTime date;
+    date.Year = d.GetYear();
+    date.Month = d.GetMonth();
+    date.Day = d.GetDay();
+    date.Hours = seconds / secondsPerHour;
+    date.Minutes = (seconds % secondsPerHour) / 60;
+    date.Seconds = seconds % 60;
+
+    return date;
+}
+
 void DomainMapper_Impl::SetFieldResult(OUString const& rResult)
 {
 #ifdef DEBUG_WRITERFILTER
@@ -4159,6 +4210,21 @@ void DomainMapper_Impl::SetFieldResult(OUString const& rResult)
                                     uno::makeAny(aValues));
                         }
                     }
+                    else if ( m_bSetDateValue )
+                    {
+                        uno::Reference< util::XNumberFormatsSupplier > xNumberSupplier( m_xTextDocument, uno::UNO_QUERY_THROW );
+
+                        uno::Reference< util::XNumberFormatter > xFormatter( ::com::sun::star::util::NumberFormatter::create( m_xComponentContext ), uno::UNO_QUERY_THROW );
+                        xFormatter->attachNumberFormatsSupplier( xNumberSupplier );
+                        sal_Int32 nKey = 0;
+
+                        uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW);
+
+                        xFieldProperties->getPropertyValue( "NumberFormat" ) >>= nKey;
+                        xFieldProperties->setPropertyValue(
+                            "DateTimeValue",
+                            uno::makeAny( lcl_dateTimeFromSerial( xFormatter->convertStringToNumber( nKey, rResult ) ) ) );
+                    }
                     else
                     {
                         uno::Reference< beans::XPropertySet > xFieldProperties( xTextField, uno::UNO_QUERY_THROW);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 535772b..30fef54 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -139,6 +139,7 @@ class FieldContext
 
     OUString                                                                 m_sCommand;
     OUString m_sResult;
+    bool m_bFieldLocked;
 
     ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField >          m_xTextField;
     ::com::sun::star::uno::Reference< ::com::sun::star::text::XFormField >          m_xFormField;
@@ -166,6 +167,9 @@ public:
     void                    SetCommandCompleted() { m_bFieldCommandCompleted = true; }
     bool                    IsCommandCompleted() const { return m_bFieldCommandCompleted;    }
 
+    void                    SetFieldLocked() { m_bFieldLocked = true; }
+    bool                    IsFieldLocked() { return m_bFieldLocked; }
+
     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >   GetCustomField() const { return m_xCustomField; }
     void    SetCustomField( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > const& xCustomField ) { m_xCustomField = xCustomField; }
     ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField >      GetTextField() const { return m_xTextField;}
@@ -330,6 +334,7 @@ private:
     FieldStack                                                                      m_aFieldStack;
     bool                                                                            m_bSetUserFieldContent;
     bool                                                                            m_bSetCitation;
+    bool                                                                            m_bSetDateValue;
     bool                                                                            m_bIsFirstSection;
     bool                                                                            m_bIsColumnBreakDeferred;
     bool                                                                            m_bIsPageBreakDeferred;
@@ -614,6 +619,8 @@ public:
     //the current field context waits for the completion of the command
     bool IsOpenFieldCommand() const;
     bool IsOpenField() const;
+    //mark field in current context as locked (fixed)
+    void SetFieldLocked();
     //collect the pieces of the command
     void AppendFieldCommand(OUString& rPartOfCommand);
     void handleFieldAsk
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index 40f5b3b..a461ed7 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -47,6 +47,7 @@ static const sal_uInt8 cFtnEdnCont = 0x4;
 static const sal_uInt8 cFieldStart = 0x13;
 static const sal_uInt8 cFieldSep = 0x14;
 static const sal_uInt8 cFieldEnd = 0x15;
+static const sal_uInt8 cFieldLock = 0x8;
 
 namespace writerfilter {
 namespace ooxml
@@ -552,6 +553,14 @@ void OOXMLFastContextHandler::endField()
     endCharacterGroup();
 }
 
+void OOXMLFastContextHandler::lockField()
+{
+    startCharacterGroup();
+    if (isForwardEvents())
+        mpStream->text(&cFieldLock, 1);
+    endCharacterGroup();
+}
+
 void OOXMLFastContextHandler::ftnednref()
 {
     if (isForwardEvents())
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
index 33ea6e0..a90fa84 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -164,6 +164,7 @@ public:
     void startField();
     void fieldSeparator();
     void endField();
+    void lockField();
     void ftnednref();
     void ftnedncont();
     void ftnednsep();
diff --git a/writerfilter/source/ooxml/OOXMLPropertySetImpl.cxx b/writerfilter/source/ooxml/OOXMLPropertySetImpl.cxx
index 52e7550..fcd7e2b 100644
--- a/writerfilter/source/ooxml/OOXMLPropertySetImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLPropertySetImpl.cxx
@@ -831,6 +831,9 @@ void OOXMLPropertySetEntryToString::attribute(Id nId, Value & rValue)
         mStr = rValue.getString();
 }
 
+/*
+  class: OOXMLPropertySetEntryToInteger
+*/
 
 OOXMLPropertySetEntryToInteger::OOXMLPropertySetEntryToInteger(Id nId)
 : mnId(nId), mnValue(0)
@@ -851,6 +854,23 @@ void OOXMLPropertySetEntryToInteger::attribute(Id nId, Value & rValue)
         mnValue = rValue.getInt();
 }
 
+/*
+  class: OOXMLPropertySetEntryToBool
+*/
+
+OOXMLPropertySetEntryToBool::OOXMLPropertySetEntryToBool(Id nId)
+    : mnId(nId), mValue(false)
+{}
+
+OOXMLPropertySetEntryToBool::~OOXMLPropertySetEntryToBool() {}
+
+void OOXMLPropertySetEntryToBool::sprm(Sprm & /*rSprm*/) {}
+
+void OOXMLPropertySetEntryToBool::attribute(Id nId, Value & rValue)
+{
+    if (nId == mnId)
+        mValue = (rValue.getInt() != 0);
+}
 
 }}
 
diff --git a/writerfilter/source/ooxml/OOXMLPropertySetImpl.hxx b/writerfilter/source/ooxml/OOXMLPropertySetImpl.hxx
index 1231600..9d3ca78 100644
--- a/writerfilter/source/ooxml/OOXMLPropertySetImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLPropertySetImpl.hxx
@@ -324,6 +324,20 @@ public:
     int getValue() const { return mnValue;}
 };
 
+class OOXMLPropertySetEntryToBool : public Properties
+{
+    Id mnId;
+    bool mValue;
+public:
+    OOXMLPropertySetEntryToBool(Id nId);
+    virtual ~OOXMLPropertySetEntryToBool();
+
+    virtual void sprm(Sprm & rSprm) SAL_OVERRIDE;
+    virtual void attribute(Id nId, Value & rValue) SAL_OVERRIDE;
+
+    bool getValue() const { return mValue; }
+};
+
 }  // namespace ooxml
 } // namespace writerfilter
 
diff --git a/writerfilter/source/ooxml/factoryimpl_ns.py b/writerfilter/source/ooxml/factoryimpl_ns.py
index 407bb49..90c7ecd 100644
--- a/writerfilter/source/ooxml/factoryimpl_ns.py
+++ b/writerfilter/source/ooxml/factoryimpl_ns.py
@@ -451,6 +451,14 @@ def factoryChooseAction(actionNode):
         ret.append("    %spHandler->fieldSeparator();" % (extra_space))
     elif actionNode.getAttribute("action") == "fieldend":
         ret.append("    %spHandler->endField();" % (extra_space))
+    elif actionNode.getAttribute("action") == "fieldlock":
+        ret.append("    %s{" % (extra_space))
+        ret.append("        %sOOXMLPropertySetEntryToBool aHandler(NS_ooxml::LN_CT_FldChar_fldLock);" % (extra_space))
+        ret.append("        %sif (OOXMLFastContextHandlerStream* pStream = dynamic_cast<OOXMLFastContextHandlerStream*>(pHandler))" % (extra_space))
+        ret.append("            %spStream->getPropertySetAttrs()->resolve(aHandler);" % (extra_space))
+        ret.append("        %sif (aHandler.getValue())" % (extra_space))
+        ret.append("            %spHandler->lockField();" % (extra_space))
+        ret.append("    %s}" % (extra_space))
     elif actionNode.getAttribute("action") == "printproperty":
         ret.append("    %sif (OOXMLFastContextHandlerStream* pStream = dynamic_cast<OOXMLFastContextHandlerStream*>(pHandler))" % extra_space)
         ret.append("    %s    pStream->sendProperty(%s);" % (extra_space, idToLabel(actionNode.getAttribute("sendtokenid"))))
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 925d7ac..fc671af 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -12521,7 +12521,7 @@
           <text/>
         </attribute>
         <attribute name="fldLock">
-          <text/>
+          <ref name="ST_OnOff"/>
         </attribute>
         <attribute name="dirty">
           <text/>
@@ -12574,7 +12574,7 @@
           <ref name="ST_FldCharType"/>
         </attribute>
         <attribute name="fldLock">
-          <text/>
+          <ref name="ST_OnOff"/>
         </attribute>
         <attribute name="dirty">
           <text/>
@@ -17511,6 +17511,7 @@
       <action name="start" action="fieldend">
         <cond tokenid="ooxml:CT_FldChar_fldCharType" value="ooxml:Value_ST_FldCharType_end"/>
       </action>
+      <action name="start" action="fieldlock"/>
     </resource>
     <resource name="CT_Hyperlink" resource="Stream">
       <attribute name="tgtFrame" tokenid="ooxml:CT_Hyperlink_tgtFrame"/>


More information about the Libreoffice-commits mailing list