[Libreoffice-commits] core.git: Branch 'distro/suse/suse-4.0' - 3 commits - sw/CppunitTest_sw_subsequent_ooxmlimport.mk sw/qa writerfilter/Library_writerfilter.mk writerfilter/source

Miklos Vajna vmiklos at suse.cz
Thu May 2 07:46:29 PDT 2013


 sw/CppunitTest_sw_subsequent_ooxmlimport.mk        |    2 
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx           |    5 
 writerfilter/Library_writerfilter.mk               |    1 
 writerfilter/source/dmapper/DomainMapper.cxx       |   59 +++++++++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx  |   10 +
 writerfilter/source/dmapper/DomainMapper_Impl.hxx  |    8 +
 writerfilter/source/dmapper/ModelEventListener.cxx |    7 +
 writerfilter/source/dmapper/SdtHelper.cxx          |  129 +++++++++++++++++++++
 writerfilter/source/dmapper/SdtHelper.hxx          |   68 +++++++++++
 writerfilter/source/ooxml/model.xml                |   12 +
 10 files changed, 299 insertions(+), 2 deletions(-)

New commits:
commit d2a2568747964858cf0fe867a3fe1bae14ad37ff
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.
    
    Change-Id: Ic1a388940bce89688e8558818f92ce9ac997609c
    (cherry picked from commit 3ec2d26dc2017ac4a27483febfc63328632f352d)
    
    Conflicts:
    	sw/CppunitTest_sw_ooxmlimport.mk
    	writerfilter/source/dmapper/DomainMapper_Impl.cxx
    	writerfilter/source/dmapper/DomainMapper_Impl.hxx

diff --git a/sw/CppunitTest_sw_subsequent_ooxmlimport.mk b/sw/CppunitTest_sw_subsequent_ooxmlimport.mk
index 48e08c5..64879c0 100644
--- a/sw/CppunitTest_sw_subsequent_ooxmlimport.mk
+++ b/sw/CppunitTest_sw_subsequent_ooxmlimport.mk
@@ -70,6 +70,7 @@ $(eval $(call gb_CppunitTest_use_components,sw_subsequent_ooxmlimport,\
     embeddedobj/util/embobj \
     fileaccess/source/fileacc \
     filter/source/config/cache/filterconfig1 \
+    forms/util/frm \
     framework/util/fwk \
     i18npool/util/i18npool \
     linguistic/source/lng \
@@ -83,6 +84,7 @@ $(eval $(call gb_CppunitTest_use_components,sw_subsequent_ooxmlimport,\
     sw/util/msword \
     sfx2/util/sfx \
     svl/source/fsstor/fsstorage \
+    svl/util/svl \
     svtools/util/svt \
     toolkit/util/tk \
     ucb/source/core/ucb1 \
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 29f3889..b735879 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -899,7 +899,10 @@ void Test::testN779627()
      */
     uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
     uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
-    uno::Reference<beans::XPropertySet> xShapeProperties( xDraws->getByIndex(2), uno::UNO_QUERY );
+    uno::Reference<beans::XPropertySet> xShapeProperties( xDraws->getByIndex(3), uno::UNO_QUERY );
+    uno::Reference<drawing::XShapeDescriptor> xShapeDescriptor(xShapeProperties, uno::UNO_QUERY);
+    // If this goes wrong, probably the index of the shape is changed and the test should be adjusted.
+    CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.RectangleShape"), xShapeDescriptor->getShapeType());
     sal_Int16 nValue;
     xShapeProperties->getPropertyValue("HoriOrient") >>= nValue;
     CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered horizontally", text::HoriOrientation::CENTER, nValue);
diff --git a/writerfilter/Library_writerfilter.mk b/writerfilter/Library_writerfilter.mk
index 98830a0..cbbd9b5 100644
--- a/writerfilter/Library_writerfilter.mk
+++ b/writerfilter/Library_writerfilter.mk
@@ -118,6 +118,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 b9db190..0e10907 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -19,6 +19,7 @@
 #include "PageBordersHandler.hxx"
 
 #include <resourcemodel/ResourceModelHelper.hxx>
+#include <SdtHelper.hxx>
 #include <DomainMapper_Impl.hxx>
 #include <ConversionHelper.hxx>
 #include <ModelEventListener.hxx>
@@ -1436,14 +1437,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:
             {
@@ -3304,6 +3305,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
@@ -3581,9 +3602,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 94b0dd7..55ae949 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -19,6 +19,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>
@@ -190,7 +191,8 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_bUsingEnhancedFields( false ),
         m_bSdt(false),
         m_xInsertTextRange(xInsertTextRange),
-        m_bIsNewDoc(bIsNewDoc)
+        m_bIsNewDoc(bIsNewDoc),
+        m_pSdtHelper(0)
 {
     appendTableManager( );
     GetBodyText();
@@ -207,6 +209,7 @@ DomainMapper_Impl::DomainMapper_Impl(
     getTableManager( ).startLevel();
     m_bUsingEnhancedFields = lcl_IsUsingEnhancedFields( m_xComponentContext );
 
+    m_pSdtHelper = new SdtHelper(*this);
 }
 
 
@@ -215,6 +218,7 @@ DomainMapper_Impl::~DomainMapper_Impl()
     RemoveLastParagraph( );
     getTableManager( ).endLevel();
     popTableManager( );
+    delete m_pSdtHelper;
 }
 
 
@@ -3900,63 +3904,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 b55d2aa..769636d 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -29,6 +29,7 @@
 #include <com/sun/star/container/XNameContainer.hpp>
 #include <vector>
 #include <stack>
+#include <boost/optional.hpp>
 
 #ifndef INCLUDED_RESOURCESIDS
 #include <doctok/resourceids.hxx>
@@ -71,6 +72,8 @@ namespace dmapper {
 
 using namespace com::sun::star;
 
+class SdtHelper;
+
 struct _PageMar
 {
     sal_Int32 top;
@@ -672,10 +675,10 @@ public:
     /// If we're importing into a new document, or just pasting to an existing one.
     bool IsNewDoc();
 
-    std::vector<OUString> m_aDropDownItems;
-    OUStringBuffer m_aSdtTexts;
-    /// Create drop-down control from w:sdt's w:dropDownList.
-    void createDropDownControl();
+    /// If we're inside <w:rPr>, inside <w:style w:type="table">
+    bool m_bInTableStyleRunProps;
+
+    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..a1b215b
--- /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, 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);
+}
+
+SdtHelper::SdtHelper(DomainMapper_Impl& rDM_Impl):
+    m_rDM_Impl(rDM_Impl)
+{
+}
+
+SdtHelper::~SdtHelper()
+{
+}
+
+void SdtHelper::createDropDownControl()
+{
+    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<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(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<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<OUString>& SdtHelper::getDropDownItems()
+{
+    return m_aDropDownItems;
+}
+
+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..d2ce372
--- /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<OUString> m_aDropDownItems;
+            /// Pieces of the default text -- currently used only by the dropdown control.
+            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<OUString>& getDropDownItems();
+            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(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 2e7aa10..33b3414 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -22772,6 +22772,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 5754e4bae126b88ac227d5f3c11707666df05f55
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
    
    Change-Id: I57d4768a26476d1a0535087c60535393b7004b24
    (cherry picked from commit 9cc1e7b165abe3f19c2919f8d9cf8efc3e8cf315)
    
    Conflicts:
    	writerfilter/source/dmapper/DomainMapper_Impl.hxx

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index d552e14..b9db190 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1436,6 +1436,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:
             {
@@ -3282,6 +3290,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
@@ -3559,6 +3581,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 deda4f1..94b0dd7 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -52,6 +52,8 @@
 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
 #include <com/sun/star/document/XViewDataSupplier.hpp>
 #include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/drawing/XControlShape.hpp>
 #include <oox/mathml/import.hxx>
 
 #ifdef DEBUG_DOMAINMAPPER
@@ -70,6 +72,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;
@@ -3896,6 +3900,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 20065e7..b55d2aa 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -671,6 +671,11 @@ public:
 
     /// If we're importing into a new document, or just pasting to an existing one.
     bool IsNewDoc();
+
+    std::vector<OUString> m_aDropDownItems;
+    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 b69fd2f..8513c27 100644
--- a/writerfilter/source/dmapper/ModelEventListener.cxx
+++ b/writerfilter/source/dmapper/ModelEventListener.cxx
@@ -27,6 +27,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 {
@@ -99,6 +101,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 89df2a2..2e7aa10 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -22756,6 +22756,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 24622ed4cc1bd75924eabfd95db2da25124983f5
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 1886188..89df2a2 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -22767,6 +22767,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