[Libreoffice-commits] core.git: Branch 'distro/suse/suse-3.6' - 3 commits - writerfilter/Library_writerfilter.mk writerfilter/source

Miklos Vajna vmiklos at suse.cz
Thu May 2 06:49:59 PDT 2013


 writerfilter/Library_writerfilter.mk               |    1 
 writerfilter/source/dmapper/DomainMapper.cxx       |   59 +++++++++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx  |   10 +
 writerfilter/source/dmapper/DomainMapper_Impl.hxx  |    5 
 writerfilter/source/dmapper/ModelEventListener.cxx |    7 +
 writerfilter/source/dmapper/SdtHelper.cxx          |  129 +++++++++++++++++++++
 writerfilter/source/dmapper/SdtHelper.hxx          |   68 +++++++++++
 writerfilter/source/ooxml/model.xml                |   12 +
 8 files changed, 290 insertions(+), 1 deletion(-)

New commits:
commit 88fc08abd3ddce062bcac889af04870c60c3814b
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Tue Apr 30 17:26:36 2013 +0200

    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

diff --git a/writerfilter/Library_writerfilter.mk b/writerfilter/Library_writerfilter.mk
index 1d62fad..a6b9596 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 9a06950..1a33f6e 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 dd94cb9..1b9fdca 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 0749414..a8dec58 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 0000000..41c6181
--- /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 0000000..72a0096
--- /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 5e40765..47971ff 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"/>
commit cf85ba066bb3493367641481e8b897b04c3cacff
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Tue Apr 30 11:44:03 2013 +0200

    bnc#779630 initial DOCX import of w:sdt's w:dropDownList
    
    (cherry picked from commit 9cc1e7b165abe3f19c2919f8d9cf8efc3e8cf315)
    
    Conflicts:
    	writerfilter/source/dmapper/DomainMapper_Impl.cxx
    	writerfilter/source/dmapper/DomainMapper_Impl.hxx
    
    Change-Id: I57d4768a26476d1a0535087c60535393b7004b24

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 231f3a1..9a06950 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1496,6 +1496,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();
+        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);
         break;
         default:
             {
@@ -3344,6 +3352,20 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType
         }
     }
     break;
+    case NS_ooxml::LN_CT_SdtPr_dropDownList:
+    {
+        writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
+        if (pProperties.get() != NULL)
+            pProperties->resolve(*this);
+    }
+    break;
+    case NS_ooxml::LN_CT_SdtDropDownList_listItem:
+    {
+        writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
+        if (pProperties.get() != NULL)
+            pProperties->resolve(*this);
+    }
+    break;
     default:
         {
 #ifdef DEBUG_DOMAINMAPPER
@@ -3621,6 +3643,12 @@ 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())
+    {
+        m_pImpl->m_aSdtTexts.append(sText);
+        return;
+    }
+
     try
     {
         m_pImpl->getTableManager().utext(data_, len);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 7f60904..dd94cb9 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -81,6 +81,8 @@
 #include <rtl/string.h>
 #include <rtl/oustringostreaminserter.hxx>
 #include "FieldTypes.hxx"
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
 #include <oox/mathml/import.hxx>
 
 #include <tools/string.hxx>
@@ -100,6 +102,8 @@
 
 #include <comphelper/configurationhelper.hxx>
 #include <comphelper/stlunosequence.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/outdev.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::rtl;
@@ -3775,6 +3779,63 @@ 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 674bc33..0749414 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -655,6 +655,11 @@ 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();
 };
 } //namespace dmapper
 } //namespace writerfilter
diff --git a/writerfilter/source/dmapper/ModelEventListener.cxx b/writerfilter/source/dmapper/ModelEventListener.cxx
index e0500fc..88cba67 100644
--- a/writerfilter/source/dmapper/ModelEventListener.cxx
+++ b/writerfilter/source/dmapper/ModelEventListener.cxx
@@ -36,6 +36,8 @@
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/text/ReferenceFieldPart.hpp>
 #include <com/sun/star/text/ReferenceFieldSource.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/view/XFormLayerAccess.hpp>
 
 namespace writerfilter {
 namespace dmapper {
@@ -108,6 +110,11 @@ void ModelEventListener::notifyEvent( const document::EventObject& rEvent ) thro
         {
             SAL_WARN("writerfilter", "exception while updating indexes: " << rEx.Message);
         }
+
+        // Form design mode is enabled by default in Writer, not in Word.
+        uno::Reference<frame::XModel> xModel(rEvent.Source, uno::UNO_QUERY);
+        uno::Reference<view::XFormLayerAccess> xFormLayerAccess(xModel->getCurrentController(), uno::UNO_QUERY);
+        xFormLayerAccess->setFormDesignMode(false);
     }
 }
 
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 262e09b..5e40765 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -22727,6 +22727,8 @@
       <element name="sdtPr" tokenid="ooxml:CT_SdtRun_sdtPr"/>
       <element name="sdtEndPr" tokenid="ooxml:CT_SdtRun_sdtEndPr"/>
       <element name="sdtContent" tokenid="ooxml:CT_SdtRun_sdtContent"/>
+      <action name="start" action="startSdt"/>
+      <action name="end" action="endSdt"/>
     </resource>
     <resource name="CT_SdtCell" resource="Stream" tag="field">
       <element name="sdtPr" tokenid="ooxml:CT_SdtCell_sdtPr"/>
commit b181233cda70ec4f1810448d76c8564ebf60c291
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Tue Apr 30 12:55:33 2013 +0200

    bnc#779630 tokenize w:listItem and w:dropDownList
    
    Change-Id: I714c2fd747eae2e706355b4fae892af9f569b3ae
    (cherry picked from commit 84be52b5f6b8a73cefd740e0bfdd5f0622c369e4)

diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 94c44c0..262e09b 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -22738,6 +22738,13 @@
       <element name="sdtEndPr" tokenid="ooxml:CT_SdtRow_sdtEndPr"/>
       <element name="sdtContent" tokenid="ooxml:CT_SdtRow_sdtContent"/>
     </resource>
+    <resource name="CT_SdtDropDownList" resource="Properties" tag="field">
+      <element name="listItem" tokenid="ooxml:CT_SdtDropDownList_listItem"/>
+    </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"/>
+    </resource>
     <resource name="CT_Attr" resource="Properties" tag="content">
       <attribute name="uri" tokenid="ooxml:CT_Attr_uri"/>
       <attribute name="name" tokenid="ooxml:CT_Attr_name"/>


More information about the Libreoffice-commits mailing list