summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@suse.cz>2013-04-30 11:44:03 +0200
committerMiklos Vajna <vmiklos@suse.cz>2013-04-30 11:57:08 +0200
commit9cc1e7b165abe3f19c2919f8d9cf8efc3e8cf315 (patch)
tree6fa14b5e08ff01d61a62ecfe144307f1349ff2b3 /writerfilter
parent10839c68caea68218e9892c4884d920b1330a61b (diff)
bnc#779630 initial DOCX import of w:sdt's w:dropDownList
Change-Id: I57d4768a26476d1a0535087c60535393b7004b24
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx28
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx61
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx5
-rw-r--r--writerfilter/source/dmapper/ModelEventListener.cxx7
-rw-r--r--writerfilter/source/ooxml/model.xml2
5 files changed, 103 insertions, 0 deletions
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<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
@@ -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 <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
@@ -66,6 +68,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;
@@ -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<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 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 <w:rPr>, inside <w:style w:type="table">
bool m_bInTableStyleRunProps;
+
+ 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 b69fd2fb4328..8513c277b20e 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 f4ecb34293b3..d9318742d4bf 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"/>