ooxml: preserve dateFormat for unchanged date controls
When saving a date control in a docx document, we were overwriting its date format with "dd/MM/yyyy" because it's tricky to support all the possible combinations. Nonetheless, there is no need to overwrite it if the date in the control remains unchanged during edition. We preserve the original date of the control, its date format and the formatted date string on import, and we compare the date in the control with the original one on export to check if we can write the old values or we have to re-generate them. Only in case the date has changed the format will be reset to "dd/MM/yyyy". We had to add an InteropGrabBag field to the XControlShape because it didn't have one, unlike other shapes. Unit tests were modified to check that the dateFormat field is preserved unchanged. Change-Id: I01e5c990e90ff190b5a6d7ea3853e049ff24ef0a
This commit is contained in:
parent
e8e4ba0b68
commit
e172825b53
@ -618,6 +618,7 @@ SfxItemPropertyMapEntry const * ImplGetSvxControlShapePropertyMap()
|
||||
// #i112587#
|
||||
{ OUString(UNO_NAME_MISC_OBJ_PRINTABLE), SDRATTR_OBJPRINTABLE , ::getBooleanCppuType(), 0, 0},
|
||||
{ OUString("Visible"), SDRATTR_OBJVISIBLE , ::getBooleanCppuType(), 0, 0},
|
||||
{ OUString(UNO_NAME_MISC_OBJ_INTEROPGRABBAG), OWN_ATTR_INTEROPGRABBAG, ::getCppuType((::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >*)0), 0, 0},
|
||||
{ OUString(), 0, css::uno::Type(), 0, 0 }
|
||||
};
|
||||
|
||||
|
Binary file not shown.
@ -2963,7 +2963,8 @@ DECLARE_OOXMLEXPORT_TEST(testDateControl, "date-control.docx")
|
||||
if (!pXmlDoc)
|
||||
return;
|
||||
assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:date", "fullDate", "2014-03-05T00:00:00Z");
|
||||
assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r/w:t", "05/03/2014");
|
||||
assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:date/w:dateFormat", "val", "dddd, dd' de 'MMMM' de 'yyyy");
|
||||
assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r/w:t", "miércoles, 05 de marzo de 2014");
|
||||
|
||||
// check imported control
|
||||
uno::Reference<drawing::XControlShape> xControl(getShape(1), uno::UNO_QUERY);
|
||||
|
@ -3599,6 +3599,25 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject)
|
||||
{
|
||||
// gather component properties
|
||||
|
||||
Date aOriginalDate(Date::EMPTY);
|
||||
OUString sOriginalContent, sDateFormat;
|
||||
uno::Sequence<beans::PropertyValue> aGrabBag;
|
||||
uno::Reference<beans::XPropertySet> xShapePropertySet(pFormObj->getUnoShape(), uno::UNO_QUERY);
|
||||
if (xShapePropertySet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= aGrabBag)
|
||||
for (sal_Int32 i=0; i < aGrabBag.getLength(); ++i)
|
||||
if (aGrabBag[i].Name == "DateFormat")
|
||||
aGrabBag[i].Value >>= sDateFormat;
|
||||
else if (aGrabBag[i].Name == "OriginalContent")
|
||||
aGrabBag[i].Value >>= sOriginalContent;
|
||||
else if (aGrabBag[i].Name == "OriginalDate")
|
||||
{
|
||||
css::util::Date aUNODate;
|
||||
aGrabBag[i].Value >>= aUNODate;
|
||||
aOriginalDate.SetDay(aUNODate.Day);
|
||||
aOriginalDate.SetMonth(aUNODate.Month);
|
||||
aOriginalDate.SetYear(aUNODate.Year);
|
||||
}
|
||||
|
||||
uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
|
||||
|
||||
OString sDate;
|
||||
@ -3610,7 +3629,17 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject)
|
||||
bHasDate = true;
|
||||
Date aDate(aUNODate.Day, aUNODate.Month, aUNODate.Year);
|
||||
sDate = DateToOString(aDate);
|
||||
aContentText = OUString::createFromAscii(DateToDDMMYYYYOString(aDate).getStr());
|
||||
|
||||
if (aOriginalDate == aDate)
|
||||
{
|
||||
aContentText = sOriginalContent;
|
||||
// sDateFormat was extracted from the grab bag
|
||||
}
|
||||
else
|
||||
{
|
||||
aContentText = OUString::createFromAscii(DateToDDMMYYYYOString(aDate).getStr());
|
||||
sDateFormat = "dd/MM/yyyy";
|
||||
}
|
||||
}
|
||||
else
|
||||
aContentText = xPropertySet->getPropertyValue("HelpText").get<OUString>();
|
||||
@ -3628,7 +3657,8 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject)
|
||||
m_pSerializer->startElementNS(XML_w, XML_date, FSEND);
|
||||
|
||||
m_pSerializer->singleElementNS(XML_w, XML_dateFormat,
|
||||
FSNS(XML_w, XML_val), "dd/MM/yyyy", //TODO: hardwired
|
||||
FSNS(XML_w, XML_val),
|
||||
rtl::OUStringToOString( sDateFormat, RTL_TEXTENCODING_UTF8 ).getStr(),
|
||||
FSEND);
|
||||
m_pSerializer->singleElementNS(XML_w, XML_lid,
|
||||
FSNS(XML_w, XML_val), "en-US", //TODO: hardwired
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <com/sun/star/drawing/XControlShape.hpp>
|
||||
#include <com/sun/star/text/VertOrientation.hpp>
|
||||
|
||||
#include <editeng/unoprnms.hxx>
|
||||
#include <vcl/outdev.hxx>
|
||||
#include <vcl/svapp.hxx>
|
||||
#include <unotools/datetime.hxx>
|
||||
@ -120,11 +121,25 @@ void SdtHelper::createDateControl(OUString& rContentText)
|
||||
else
|
||||
xPropertySet->setPropertyValue("HelpText", uno::makeAny(rContentText));
|
||||
|
||||
// append date format to grab bag
|
||||
uno::Sequence<beans::PropertyValue> aGrabBag(3);
|
||||
aGrabBag[0].Name = "OriginalDate";
|
||||
aGrabBag[0].Value = uno::makeAny(aDate);
|
||||
aGrabBag[1].Name = "OriginalContent";
|
||||
aGrabBag[1].Value = uno::makeAny(rContentText);
|
||||
aGrabBag[2].Name = "DateFormat";
|
||||
aGrabBag[2].Value = uno::makeAny(sDateFormat);
|
||||
|
||||
std::vector<OUString> aItems;
|
||||
createControlShape(lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), rContentText, aItems), xControlModel);
|
||||
createControlShape(lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), rContentText, aItems), xControlModel, aGrabBag);
|
||||
}
|
||||
|
||||
void SdtHelper::createControlShape(awt::Size aSize, uno::Reference<awt::XControlModel> xControlModel)
|
||||
{
|
||||
createControlShape(aSize, xControlModel, uno::Sequence<beans::PropertyValue>());
|
||||
}
|
||||
|
||||
void SdtHelper::createControlShape(awt::Size aSize, uno::Reference<awt::XControlModel> xControlModel, uno::Sequence<beans::PropertyValue> rGrabBag)
|
||||
{
|
||||
uno::Reference<drawing::XControlShape> xControlShape(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.drawing.ControlShape"), uno::UNO_QUERY);
|
||||
xControlShape->setSize(aSize);
|
||||
@ -133,6 +148,9 @@ void SdtHelper::createControlShape(awt::Size aSize, uno::Reference<awt::XControl
|
||||
uno::Reference<beans::XPropertySet> xPropertySet(xControlShape, uno::UNO_QUERY);
|
||||
xPropertySet->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::CENTER));
|
||||
|
||||
if(rGrabBag.hasElements())
|
||||
xPropertySet->setPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG, uno::makeAny(rGrabBag));
|
||||
|
||||
uno::Reference<text::XTextContent> xTextContent(xControlShape, uno::UNO_QUERY);
|
||||
m_rDM_Impl.appendTextContent(xTextContent, uno::Sequence< beans::PropertyValue >());
|
||||
m_bHasElements = true;
|
||||
|
@ -60,6 +60,8 @@ class SdtHelper
|
||||
|
||||
/// Create and append the drawing::XControlShape, containing the various models.
|
||||
void createControlShape(com::sun::star::awt::Size aSize, com::sun::star::uno::Reference<com::sun::star::awt::XControlModel>);
|
||||
void createControlShape(com::sun::star::awt::Size aSize, com::sun::star::uno::Reference<com::sun::star::awt::XControlModel>,
|
||||
com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> rGrabBag);
|
||||
public:
|
||||
SdtHelper(DomainMapper_Impl& rDM_Impl);
|
||||
virtual ~SdtHelper();
|
||||
|
Loading…
x
Reference in New Issue
Block a user