From 9cc1e7b165abe3f19c2919f8d9cf8efc3e8cf315 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 30 Apr 2013 11:44:03 +0200 Subject: bnc#779630 initial DOCX import of w:sdt's w:dropDownList Change-Id: I57d4768a26476d1a0535087c60535393b7004b24 --- writerfilter/source/dmapper/DomainMapper.cxx | 28 ++++++++++ writerfilter/source/dmapper/DomainMapper_Impl.cxx | 61 ++++++++++++++++++++++ writerfilter/source/dmapper/DomainMapper_Impl.hxx | 5 ++ writerfilter/source/dmapper/ModelEventListener.cxx | 7 +++ writerfilter/source/ooxml/model.xml | 2 + 5 files changed, 103 insertions(+) (limited to 'writerfilter') diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 4e07c47243fd..4d6f9055fb98 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -1435,6 +1435,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: { @@ -3289,6 +3297,20 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType } } break; + case NS_ooxml::LN_CT_SdtPr_dropDownList: + { + writerfilter::Reference::Pointer_t pProperties = rSprm.getProps(); + if (pProperties.get() != NULL) + pProperties->resolve(*this); + } + break; + case NS_ooxml::LN_CT_SdtDropDownList_listItem: + { + writerfilter::Reference::Pointer_t pProperties = rSprm.getProps(); + if (pProperties.get() != NULL) + pProperties->resolve(*this); + } + break; default: { #ifdef DEBUG_DOMAINMAPPER @@ -3580,6 +3602,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 6de9889338b0..854179f51436 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include #ifdef DEBUG_DOMAINMAPPER @@ -66,6 +68,8 @@ #include #include +#include +#include using namespace ::com::sun::star; using namespace ::rtl; @@ -3933,6 +3937,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& 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()); + PropertyMap::iterator aHeight = pDefaultCharProps->find(PropertyDefinition(PROP_CHAR_HEIGHT, false)); + if (aHeight != pDefaultCharProps->end()) + { + nHeight = aHeight->second.get() * 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 xControlModel(m_xTextFactory->createInstance("com.sun.star.form.component.ComboBox"), uno::UNO_QUERY); + uno::Reference xPropertySet(xControlModel, uno::UNO_QUERY); + xPropertySet->setPropertyValue("DefaultText", uno::makeAny(aDefaultText)); + xPropertySet->setPropertyValue("Dropdown", uno::makeAny(sal_True)); + uno::Sequence 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 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 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 11adedfd4624..68fe0aeac626 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -678,6 +678,11 @@ public: /// If we're inside , inside bool m_bInTableStyleRunProps; + + std::vector 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 b69fd2fb4328..8513c277b20e 100644 --- a/writerfilter/source/dmapper/ModelEventListener.cxx +++ b/writerfilter/source/dmapper/ModelEventListener.cxx @@ -27,6 +27,8 @@ #include #include #include +#include +#include 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 xModel(rEvent.Source, uno::UNO_QUERY); + uno::Reference xFormLayerAccess(xModel->getCurrentController(), uno::UNO_QUERY); + xFormLayerAccess->setFormDesignMode(false); } } diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index f4ecb34293b3..d9318742d4bf 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -22756,6 +22756,8 @@ + + -- cgit