summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@suse.cz>2013-04-30 17:26:36 +0200
committerMiklos Vajna <vmiklos@suse.cz>2013-05-02 15:07:25 +0200
commit88fc08abd3ddce062bcac889af04870c60c3814b (patch)
tree8a873551d6344cee2b15ef4e12a23498d0b45bc3
parentcf85ba066bb3493367641481e8b897b04c3cacff (diff)
bnc#779630 initial DOCX import of w:sdt's w:date
Also factor out the w:sdt-related methods to a helper class to avoid DomainMapper_Impl become a God object. (cherry picked from commit 3ec2d26dc2017ac4a27483febfc63328632f352d) Conflicts: sw/CppunitTest_sw_ooxmlimport.mk sw/qa/extras/ooxmlimport/ooxmlimport.cxx writerfilter/source/dmapper/DomainMapper_Impl.cxx writerfilter/source/dmapper/DomainMapper_Impl.hxx Change-Id: Ic1a388940bce89688e8558818f92ce9ac997609c
-rw-r--r--writerfilter/Library_writerfilter.mk1
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx41
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx63
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx8
-rw-r--r--writerfilter/source/dmapper/SdtHelper.cxx129
-rw-r--r--writerfilter/source/dmapper/SdtHelper.hxx68
-rw-r--r--writerfilter/source/ooxml/model.xml3
7 files changed, 246 insertions, 67 deletions
diff --git a/writerfilter/Library_writerfilter.mk b/writerfilter/Library_writerfilter.mk
index 1d62fad49e74..a6b959613528 100644
--- a/writerfilter/Library_writerfilter.mk
+++ b/writerfilter/Library_writerfilter.mk
@@ -111,6 +111,7 @@ $(eval $(call gb_Library_add_exception_objects,writerfilter,\
writerfilter/source/dmapper/PropertyIds \
writerfilter/source/dmapper/PropertyMap \
writerfilter/source/dmapper/PropertyMapHelper \
+ writerfilter/source/dmapper/SdtHelper \
writerfilter/source/dmapper/SectionColumnHandler \
writerfilter/source/dmapper/SettingsTable \
writerfilter/source/dmapper/StyleSheetTable \
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 9a06950b8986..1a33f6e8fa04 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -28,6 +28,7 @@
#include "PageBordersHandler.hxx"
#include <resourcemodel/ResourceModelHelper.hxx>
+#include <SdtHelper.hxx>
#include <DomainMapper_Impl.hxx>
#include <ConversionHelper.hxx>
#include <ModelEventListener.hxx>
@@ -1496,14 +1497,14 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
break;
case NS_ooxml::LN_CT_SdtBlock_sdtEndContent:
m_pImpl->SetSdt(false);
- if (!m_pImpl->m_aDropDownItems.empty())
- m_pImpl->createDropDownControl();
+ if (!m_pImpl->m_pSdtHelper->getDropDownItems().empty())
+ m_pImpl->m_pSdtHelper->createDropDownControl();
break;
case NS_ooxml::LN_CT_SdtListItem_displayText:
// TODO handle when this is != value
break;
case NS_ooxml::LN_CT_SdtListItem_value:
- m_pImpl->m_aDropDownItems.push_back(sStringValue);
+ m_pImpl->m_pSdtHelper->getDropDownItems().push_back(sStringValue);
break;
default:
{
@@ -3366,6 +3367,26 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType
pProperties->resolve(*this);
}
break;
+ case NS_ooxml::LN_CT_SdtPr_date:
+ {
+ writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
+ if (pProperties.get() != NULL)
+ pProperties->resolve(*this);
+ }
+ break;
+ case NS_ooxml::LN_CT_SdtDate_dateFormat:
+ {
+ if (sStringValue == "M/d/yyyy")
+ // See com/sun/star/awt/UnoControlDateFieldModel.idl, DateFormat; sadly there are no constants for this.
+ m_pImpl->m_pSdtHelper->getDateFormat().reset(8);
+ else
+ {
+ // Set default format, so at least the date picker is created.
+ m_pImpl->m_pSdtHelper->getDateFormat().reset(0);
+ SAL_WARN("writerfilter", "unhandled w:dateFormat value");
+ }
+ }
+ break;
default:
{
#ifdef DEBUG_DOMAINMAPPER
@@ -3643,9 +3664,19 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
aBuffer.append( (const sal_Unicode *) data_, len);
sText = aBuffer.makeStringAndClear();
- if (!m_pImpl->m_aDropDownItems.empty())
+ if (!m_pImpl->m_pSdtHelper->getDropDownItems().empty())
{
- m_pImpl->m_aSdtTexts.append(sText);
+ m_pImpl->m_pSdtHelper->getSdtTexts().append(sText);
+ return;
+ }
+ else if (m_pImpl->m_pSdtHelper->getDateFormat())
+ {
+ /*
+ * 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);
return;
}
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index dd94cb96b612..1b9fdca6047c 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -28,6 +28,7 @@
#include <DomainMapper_Impl.hxx>
#include <ConversionHelper.hxx>
+#include <SdtHelper.hxx>
#include <DomainMapperTableHandler.hxx>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
@@ -218,7 +219,8 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bParaSectpr( false ),
m_bUsingEnhancedFields( false ),
m_bSdt(false),
- m_bIsNewDoc(bIsNewDoc)
+ m_bIsNewDoc(bIsNewDoc),
+ m_pSdtHelper(0)
{
appendTableManager( );
GetBodyText();
@@ -234,6 +236,7 @@ DomainMapper_Impl::DomainMapper_Impl(
getTableManager( ).startLevel();
m_bUsingEnhancedFields = lcl_IsUsingEnhancedFields( uno::Reference< lang::XMultiServiceFactory >( m_xComponentContext->getServiceManager(), uno::UNO_QUERY ) );
+ m_pSdtHelper = new SdtHelper(*this);
}
@@ -242,6 +245,7 @@ DomainMapper_Impl::~DomainMapper_Impl()
RemoveLastParagraph( );
getTableManager( ).endLevel();
popTableManager( );
+ delete m_pSdtHelper;
}
@@ -3779,63 +3783,6 @@ bool DomainMapper_Impl::IsNewDoc()
return m_bIsNewDoc;
}
-/// w:sdt's w:dropDownList doesn't have width, so guess the size based on the longest string.
-awt::Size lcl_getOptimalWidth(StyleSheetTablePtr pStyleSheet, OUString& rDefault, std::vector<OUString>& rItems)
-{
- OUString aLongest = rDefault;
- sal_Int32 nHeight = 0;
- for (size_t i = 0; i < rItems.size(); ++i)
- if (rItems[i].getLength() > aLongest.getLength())
- aLongest = rItems[i];
-
- MapMode aMap(MAP_100TH_MM);
- OutputDevice* pOut = Application::GetDefaultDevice();
- pOut->Push(PUSH_FONT | PUSH_MAPMODE);
-
- PropertyMapPtr pDefaultCharProps = pStyleSheet->GetDefaultCharProps();
- Font aFont(pOut->GetFont());
- PropertyMap::iterator aFontName = pDefaultCharProps->find(PropertyDefinition(PROP_CHAR_FONT_NAME, false));
- if (aFontName != pDefaultCharProps->end())
- aFont.SetName(aFontName->second.get<OUString>());
- PropertyMap::iterator aHeight = pDefaultCharProps->find(PropertyDefinition(PROP_CHAR_HEIGHT, false));
- if (aHeight != pDefaultCharProps->end())
- {
- nHeight = aHeight->second.get<double>() * 35; // points -> mm100
- aFont.SetSize(Size(0, nHeight));
- }
- pOut->SetFont(aFont);
- pOut->SetMapMode(aMap);
- sal_Int32 nWidth = pOut->GetTextWidth(aLongest);
-
- pOut->Pop();
- // Width: space for the text + the square having the dropdown arrow.
- return awt::Size(nWidth + nHeight, nHeight);
-}
-
-void DomainMapper_Impl::createDropDownControl()
-{
- OUString aDefaultText = m_aSdtTexts.makeStringAndClear();
- uno::Reference<awt::XControlModel> xControlModel(m_xTextFactory->createInstance("com.sun.star.form.component.ComboBox"), uno::UNO_QUERY);
- uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
- xPropertySet->setPropertyValue("DefaultText", uno::makeAny(aDefaultText));
- xPropertySet->setPropertyValue("Dropdown", uno::makeAny(sal_True));
- uno::Sequence<OUString> aItems(m_aDropDownItems.size());
- for (size_t i = 0; i < m_aDropDownItems.size(); ++i)
- aItems[i] = m_aDropDownItems[i];
- xPropertySet->setPropertyValue("StringItemList", uno::makeAny(aItems));
-
- uno::Reference<drawing::XControlShape> xControlShape(m_xTextFactory->createInstance("com.sun.star.drawing.ControlShape"), uno::UNO_QUERY);
- xControlShape->setSize(lcl_getOptimalWidth(GetStyleSheetTable(), aDefaultText, m_aDropDownItems));
- m_aDropDownItems.clear();
- xControlShape->setControl(xControlModel);
-
- xPropertySet.set(xControlShape, uno::UNO_QUERY);
- xPropertySet->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::CENTER));
-
- uno::Reference<text::XTextContent> xTextContent(xControlShape, uno::UNO_QUERY);
- appendTextContent(xTextContent, uno::Sequence< beans::PropertyValue >());
-}
-
}}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 074941464626..a8dec58fce46 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -37,6 +37,7 @@
#include <com/sun/star/container/XNameContainer.hpp>
#include <vector>
#include <stack>
+#include <boost/optional.hpp>
#ifndef INCLUDED_RESOURCESIDS
#include <doctok/resourceids.hxx>
@@ -79,6 +80,8 @@ namespace dmapper {
using namespace com::sun::star;
+class SdtHelper;
+
struct _PageMar
{
sal_Int32 top;
@@ -656,10 +659,7 @@ public:
/// If we're importing into a new document, or just pasting to an existing one.
bool IsNewDoc();
- std::vector<rtl::OUString> m_aDropDownItems;
- rtl::OUStringBuffer m_aSdtTexts;
- /// Create drop-down control from w:sdt's w:dropDownList.
- void createDropDownControl();
+ SdtHelper* m_pSdtHelper;
};
} //namespace dmapper
} //namespace writerfilter
diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx
new file mode 100644
index 000000000000..41c6181ff6d2
--- /dev/null
+++ b/writerfilter/source/dmapper/SdtHelper.cxx
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <com/sun/star/awt/Size.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+
+#include <vcl/outdev.hxx>
+#include <vcl/svapp.hxx>
+
+#include <DomainMapper_Impl.hxx>
+#include <StyleSheetTable.hxx>
+#include <SdtHelper.hxx>
+
+namespace writerfilter {
+namespace dmapper {
+
+using namespace ::com::sun::star;
+
+/// w:sdt's w:dropDownList doesn't have width, so guess the size based on the longest string.
+awt::Size lcl_getOptimalWidth(StyleSheetTablePtr pStyleSheet, rtl::OUString& rDefault, std::vector<rtl::OUString>& rItems)
+{
+ rtl::OUString aLongest = rDefault;
+ sal_Int32 nHeight = 0;
+ for (size_t i = 0; i < rItems.size(); ++i)
+ if (rItems[i].getLength() > aLongest.getLength())
+ aLongest = rItems[i];
+
+ MapMode aMap(MAP_100TH_MM);
+ OutputDevice* pOut = Application::GetDefaultDevice();
+ pOut->Push(PUSH_FONT | PUSH_MAPMODE);
+
+ PropertyMapPtr pDefaultCharProps = pStyleSheet->GetDefaultCharProps();
+ Font aFont(pOut->GetFont());
+ PropertyMap::iterator aFontName = pDefaultCharProps->find(PropertyDefinition(PROP_CHAR_FONT_NAME, false));
+ if (aFontName != pDefaultCharProps->end())
+ aFont.SetName(aFontName->second.get<rtl::OUString>());
+ PropertyMap::iterator aHeight = pDefaultCharProps->find(PropertyDefinition(PROP_CHAR_HEIGHT, false));
+ if (aHeight != pDefaultCharProps->end())
+ {
+ nHeight = aHeight->second.get<double>() * 35; // points -> mm100
+ aFont.SetSize(Size(0, nHeight));
+ }
+ pOut->SetFont(aFont);
+ pOut->SetMapMode(aMap);
+ sal_Int32 nWidth = pOut->GetTextWidth(aLongest);
+
+ pOut->Pop();
+ // Width: space for the text + the square having the dropdown arrow.
+ return awt::Size(nWidth + nHeight, nHeight);
+}
+
+SdtHelper::SdtHelper(DomainMapper_Impl& rDM_Impl):
+ m_rDM_Impl(rDM_Impl)
+{
+}
+
+SdtHelper::~SdtHelper()
+{
+}
+
+void SdtHelper::createDropDownControl()
+{
+ rtl::OUString aDefaultText = m_aSdtTexts.makeStringAndClear();
+ uno::Reference<awt::XControlModel> xControlModel(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.form.component.ComboBox"), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
+ xPropertySet->setPropertyValue("DefaultText", uno::makeAny(aDefaultText));
+ xPropertySet->setPropertyValue("Dropdown", uno::makeAny(sal_True));
+ uno::Sequence<rtl::OUString> aItems(m_aDropDownItems.size());
+ for (size_t i = 0; i < m_aDropDownItems.size(); ++i)
+ aItems[i] = m_aDropDownItems[i];
+ xPropertySet->setPropertyValue("StringItemList", uno::makeAny(aItems));
+
+ createControlShape(lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), aDefaultText, m_aDropDownItems), xControlModel);
+ m_aDropDownItems.clear();
+}
+
+void SdtHelper::createDateControl(rtl::OUString& rDefaultText)
+{
+ uno::Reference<awt::XControlModel> xControlModel(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.form.component.DateField"), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
+ xPropertySet->setPropertyValue("HelpText", uno::makeAny(rDefaultText));
+ xPropertySet->setPropertyValue("Dropdown", uno::makeAny(sal_True));
+ xPropertySet->setPropertyValue("DateFormat", uno::makeAny(*m_oDateFormat));
+ m_oDateFormat.reset();
+
+ std::vector<rtl::OUString> aItems;
+ createControlShape(lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), rDefaultText, aItems), xControlModel);
+}
+
+void SdtHelper::createControlShape(awt::Size aSize, uno::Reference<awt::XControlModel> xControlModel)
+{
+ uno::Reference<drawing::XControlShape> xControlShape(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.drawing.ControlShape"), uno::UNO_QUERY);
+ xControlShape->setSize(aSize);
+ xControlShape->setControl(xControlModel);
+
+ uno::Reference<beans::XPropertySet> xPropertySet(xControlShape, uno::UNO_QUERY);
+ xPropertySet->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::CENTER));
+
+ uno::Reference<text::XTextContent> xTextContent(xControlShape, uno::UNO_QUERY);
+ m_rDM_Impl.appendTextContent(xTextContent, uno::Sequence< beans::PropertyValue >());
+}
+
+std::vector<rtl::OUString>& SdtHelper::getDropDownItems()
+{
+ return m_aDropDownItems;
+}
+
+rtl::OUStringBuffer& SdtHelper::getSdtTexts()
+{
+ return m_aSdtTexts;
+}
+
+boost::optional<sal_Int16>& SdtHelper::getDateFormat()
+{
+ return m_oDateFormat;
+}
+
+} // namespace dmapper
+} // namespace writerfilter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx
new file mode 100644
index 000000000000..72a0096bd1c7
--- /dev/null
+++ b/writerfilter/source/dmapper/SdtHelper.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SDTHELPER_HXX
+#define INCLUDED_SDTHELPER_HXX
+
+#include <boost/optional.hpp>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <rtl/ustrbuf.hxx>
+
+#include <WriterFilterDllApi.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace awt{
+ struct Size;
+ class XControlModel;
+ }
+}}}
+
+namespace writerfilter {
+ namespace dmapper {
+
+ /**
+ * Helper to create form controls from w:sdt tokens.
+ *
+ * w:sdt tokens can't be imported as form fields, as w:sdt supports
+ * e.g. date picking as well.
+ */
+ class SdtHelper
+ {
+ DomainMapper_Impl& m_rDM_Impl;
+
+ /// Items of the drop-down control.
+ std::vector<rtl::OUString> m_aDropDownItems;
+ /// Pieces of the default text -- currently used only by the dropdown control.
+ rtl::OUStringBuffer m_aSdtTexts;
+ /// Date format, see com/sun/star/awt/UnoControlDateFieldModel.idl
+ boost::optional<sal_Int16> m_oDateFormat;
+
+ /// 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>);
+ public:
+ SdtHelper(DomainMapper_Impl& rDM_Impl);
+ virtual ~SdtHelper();
+
+ std::vector<rtl::OUString>& getDropDownItems();
+ rtl::OUStringBuffer& getSdtTexts();
+ boost::optional<sal_Int16>& getDateFormat();
+
+ /// Create drop-down control from w:sdt's w:dropDownList.
+ void createDropDownControl();
+ /// Create date control from w:sdt's w:date.
+ void createDateControl(rtl::OUString& rDefaultText);
+ };
+
+ } // namespace dmapper
+} // namespace writerfilter
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 5e40765f9a56..47971ff529d3 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -22743,6 +22743,9 @@
<resource name="CT_SdtDropDownList" resource="Properties" tag="field">
<element name="listItem" tokenid="ooxml:CT_SdtDropDownList_listItem"/>
</resource>
+ <resource name="CT_SdtDate" resource="Properties" tag="field">
+ <element name="dateFormat" tokenid="ooxml:CT_SdtDate_dateFormat"/>
+ </resource>
<resource name="CT_SdtListItem" resource="Properties" tag="field">
<attribute name="displayText" tokenid="ooxml:CT_SdtListItem_displayText"/>
<attribute name="value" tokenid="ooxml:CT_SdtListItem_value"/>