diff options
author | Tamás Zolnai <tamas.zolnai@collabora.com> | 2019-07-02 21:09:25 +0200 |
---|---|---|
committer | Tamás Zolnai <tamas.zolnai@collabora.com> | 2019-07-12 05:52:28 +0200 |
commit | df4fe4504f6d966d1d92433862dc1baf2ba008d4 (patch) | |
tree | 4ba47bb539723acfaa67e5f9f415ebe0100d2920 /writerfilter | |
parent | 865bfe5cc95c11ab7273bd3ac74cd4f4bd9e097e (diff) |
MSForms: DOCX import of text-based date field
* Before the date content control was imported as LO specific
date form control, but now I changed it to be imported into
the compatible text-based date field.
* Also removed the things stored in the grabbag, which are useless now.
* Disabled some unit tests, I'll update them for the new field
in other patches.
Change-Id: Ide8f4b27ec6b2dbb182abb4180229736bf9c434f
Reviewed-on: https://gerrit.libreoffice.org/75447
Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com>
Tested-by: Tamás Zolnai <tamas.zolnai@collabora.com>
Diffstat (limited to 'writerfilter')
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 21 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 4 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.hxx | 1 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SdtHelper.cxx | 111 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SdtHelper.hxx | 2 |
5 files changed, 44 insertions, 95 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 972ee68eeb15..72b647cb24b8 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -1019,6 +1019,8 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) if (!m_pImpl->m_pSdtHelper->getDropDownItems().empty()) m_pImpl->m_pSdtHelper->createDropDownControl(); + else if (m_pImpl->m_pSdtHelper->validateDateFormat() && !IsInHeaderFooter()) + m_pImpl->m_pSdtHelper->createDateContentControl(); break; case NS_ooxml::LN_CT_SdtListItem_displayText: // TODO handle when this is != value @@ -2431,16 +2433,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) break; case NS_ooxml::LN_CT_SdtPr_date: { - if (!IsInHeaderFooter()) - resolveSprmProps(*this, rSprm); - else - { - OUString sName = "ooxml:CT_SdtPr_date"; - enableInteropGrabBag(sName); - resolveSprmProps(*this, rSprm); - m_pImpl->m_pSdtHelper->appendToInteropGrabBag(getInteropGrabBag()); - m_pImpl->disableInteropGrabBag(); - } + resolveSprmProps(*this, rSprm); } break; case NS_ooxml::LN_CT_SdtDate_dateFormat: @@ -3240,12 +3233,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) // Form controls are not allowed in headers / footers; see sw::DocumentContentOperationsManager::InsertDrawObj() else if (m_pImpl->m_pSdtHelper->validateDateFormat() && !IsInHeaderFooter()) { - /* - * Here we assume w:sdt only contains a single text token. We need to - * create the control early, as in Writer, it's part of the cell, but - * in OOXML, the sdt contains the cell. - */ - m_pImpl->m_pSdtHelper->createDateControl(sText, getInteropGrabBag()); + // date field is imported, we don't need the corresponding date text return; } else if (!m_pImpl->m_pSdtHelper->isInteropGrabBagEmpty()) @@ -3262,7 +3250,6 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_text") || m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_dataBinding") || m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_citation") || - m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_date") || (m_pImpl->m_pSdtHelper->containedInInteropGrabBag("ooxml:CT_SdtPr_id") && m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph()) { diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index e14e672aa816..51b5c1e2cf96 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -617,6 +617,10 @@ PropertyMapPtr DomainMapper_Impl::GetTopContextOfType(ContextType eId) return pRet; } +bool DomainMapper_Impl::HasTopText() const +{ + return !m_aTextAppendStack.empty(); +} uno::Reference< text::XTextAppend > const & DomainMapper_Impl::GetTopTextAppend() { diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 1c4c4f3038a3..040b8df0cc28 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -666,6 +666,7 @@ public: } PropertyMapPtr GetTopContextOfType(ContextType eId); + bool HasTopText() const; css::uno::Reference<css::text::XTextAppend> const & GetTopTextAppend(); FieldContextPtr const & GetTopFieldContext(); diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx index 0b870749313b..c55ceaec0d65 100644 --- a/writerfilter/source/dmapper/SdtHelper.cxx +++ b/writerfilter/source/dmapper/SdtHelper.cxx @@ -21,30 +21,11 @@ #include <vcl/outdev.hxx> #include <unotools/datetime.hxx> #include <comphelper/sequence.hxx> +#include <xmloff/odffields.hxx> #include "DomainMapper_Impl.hxx" #include "StyleSheetTable.hxx" -namespace -{ -/// Maps OOXML <w:dateFormat> values to UNO date format values. -sal_Int16 getUNODateFormat(const OUString& rDateFormat) -{ - // See com/sun/star/awt/UnoControlDateFieldModel.idl, DateFormat; sadly - // there are no constants. - sal_Int16 nDateFormat = -1; - - if (rDateFormat == "M/d/yyyy" || rDateFormat == "M.d.yyyy") - // MMDDYYYY - nDateFormat = 8; - else if (rDateFormat == "dd/MM/yyyy") - // DDMMYYYY - nDateFormat = 7; - - return nDateFormat; -} -} - namespace writerfilter { namespace dmapper @@ -115,70 +96,46 @@ void SdtHelper::createDropDownControl() bool SdtHelper::validateDateFormat() { - bool bRet = !m_sDate.isEmpty() || getUNODateFormat(m_sDateFormat.toString()) != -1; - if (!bRet) - m_sDateFormat.setLength(0); - return bRet; + return !m_sDateFormat.toString().isEmpty() && !m_sLocale.toString().isEmpty(); } -void SdtHelper::createDateControl(OUString const& rContentText, const beans::PropertyValue& rCharFormat) +void SdtHelper::createDateContentControl() { - uno::Reference<awt::XControlModel> xControlModel; - try + uno::Reference<text::XTextCursor> xCrsr; + if(m_rDM_Impl.HasTopText()) { - xControlModel.set(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.form.component.DateField"), uno::UNO_QUERY_THROW); + uno::Reference<text::XTextAppend> xTextAppend = m_rDM_Impl.GetTopTextAppend(); + if (xTextAppend.is()) + xCrsr = xTextAppend->createTextCursorByRange(xTextAppend->getEnd()); } - catch (css::uno::RuntimeException&) + if (xCrsr.is()) { - throw; + uno::Reference< uno::XInterface > xFieldInterface; + xFieldInterface = m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.text.FormFieldmark"); + uno::Reference< text::XFormField > xFormField( xFieldInterface, uno::UNO_QUERY ); + uno::Reference< text::XTextContent > xToInsert(xFormField, uno::UNO_QUERY); + if ( xFormField.is() && xToInsert.is() ) + { + xCrsr->gotoEnd(true); + xToInsert->attach( uno::Reference< text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW )); + xFormField->setFieldType(ODF_FORMDATE); + uno::Reference<container::XNameContainer> xNameCont = xFormField->getParameters(); + if(xNameCont.is()) + { + xNameCont->insertByName(ODF_FORMDATE_DATEFORMAT, uno::makeAny(m_sDateFormat.makeStringAndClear())); + xNameCont->insertByName(ODF_FORMDATE_DATEFORMAT_LANGUAGE, uno::makeAny(m_sLocale.makeStringAndClear())); + OUString sDate = m_sDate.makeStringAndClear(); + if(!sDate.isEmpty()) + { + // Remove time part of the full date + sal_Int32 nTimeSep = sDate.indexOf("T"); + if(nTimeSep != -1) + sDate = sDate.copy(0, nTimeSep); + xNameCont->insertByName(ODF_FORMDATE_CURRENTDATE, uno::makeAny(sDate)); + } + } + } } - catch (css::uno::Exception& e) - { - css::uno::Any a(cppu::getCaughtException()); - throw css::lang::WrappedTargetRuntimeException("wrapped " + a.getValueTypeName() + ": " + e.Message, css::uno::Reference<css::uno::XInterface>(), a); - } - uno::Reference<beans::XPropertySet> xPropertySet( - xControlModel, uno::UNO_QUERY_THROW); - - xPropertySet->setPropertyValue("Dropdown", uno::makeAny(true)); - - // See com/sun/star/awt/UnoControlDateFieldModel.idl, DateFormat; sadly there are no constants - OUString sDateFormat = m_sDateFormat.makeStringAndClear(); - sal_Int16 nDateFormat = getUNODateFormat(sDateFormat); - if (nDateFormat == -1) - { - // Set default format, so at least the date picker is created. - SAL_WARN("writerfilter", "unhandled w:dateFormat value"); - if (m_sDate.isEmpty()) - return; - nDateFormat = 0; - } - xPropertySet->setPropertyValue("DateFormat", uno::makeAny(nDateFormat)); - - util::Date aDate; - util::DateTime aDateTime; - if (utl::ISO8601parseDateTime(m_sDate.makeStringAndClear(), aDateTime)) - { - utl::extractDate(aDateTime, aDate); - xPropertySet->setPropertyValue("Date", uno::makeAny(aDate)); - } - else - xPropertySet->setPropertyValue("HelpText", uno::makeAny(rContentText.trim())); - - // append date format to grab bag - comphelper::SequenceAsHashMap aGrabBag; - aGrabBag["OriginalDate"] <<= aDate; - aGrabBag["OriginalContent"] <<= rContentText; - aGrabBag["DateFormat"] <<= sDateFormat; - aGrabBag["Locale"] <<= m_sLocale.makeStringAndClear(); - aGrabBag["CharFormat"] = rCharFormat.Value; - // merge in properties like ooxml:CT_SdtPr_alias and friends. - aGrabBag.update(comphelper::SequenceAsHashMap(comphelper::containerToSequence(m_aGrabBag))); - // and empty the property list, so they won't end up on the next sdt as well - m_aGrabBag.clear(); - - std::vector<OUString> aItems; - createControlShape(lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), rContentText, aItems), xControlModel, aGrabBag.getAsConstPropertyValueList()); } void SdtHelper::createControlShape(awt::Size aSize, uno::Reference<awt::XControlModel> const& xControlModel, const uno::Sequence<beans::PropertyValue>& rGrabBag) diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx index 91f005f9d544..01abd4117adb 100644 --- a/writerfilter/source/dmapper/SdtHelper.hxx +++ b/writerfilter/source/dmapper/SdtHelper.hxx @@ -114,7 +114,7 @@ public: /// Create drop-down control from w:sdt's w:dropDownList. void createDropDownControl(); /// Create date control from w:sdt's w:date. - void createDateControl(OUString const& rContentText, const css::beans::PropertyValue& rCharFormat); + void createDateContentControl(); void appendToInteropGrabBag(const css::beans::PropertyValue& rValue); css::uno::Sequence<css::beans::PropertyValue> getInteropGrabBagAndClear(); |