summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEilidh McAdam <eilidh.mcadam@itomig.de>2014-12-10 03:50:10 +0000
committerMiklos Vajna <vmiklos@collabora.co.uk>2014-12-19 18:20:28 +0100
commit8826934016d60d0a4a1e824e3f1cff814d915515 (patch)
treeca1a860c96110c9f72e619f150d69ce4bcd5be52
parent3726737273e488ffab02f4a2dded5640521729cb (diff)
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
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx4
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx76
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx7
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.cxx9
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.hxx1
-rw-r--r--writerfilter/source/ooxml/OOXMLPropertySetImpl.cxx20
-rw-r--r--writerfilter/source/ooxml/OOXMLPropertySetImpl.hxx14
-rw-r--r--writerfilter/source/ooxml/factoryimpl_ns.py8
-rw-r--r--writerfilter/source/ooxml/model.xml5
9 files changed, 137 insertions, 7 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index ec5afab1440a..2f0e43d64ec5 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 d080ae84c1e1..a3694bd9e660 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 535772bc17d6..30fef54df9d7 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 40f5b3b5c5fc..a461ed7089ac 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 33ea6e02f0cd..a90fa8419cb5 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 52e755061e5e..fcd7e2bd8d6e 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 123160015a70..9d3ca78c8399 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 407bb49898eb..90c7ecdd2a8c 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 925d7ac88667..fc671afda9b5 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"/>