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 <vmik...@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 <vmik...@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 <vmik...@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"/> _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits