Bump version to 4.3-4
[LibreOffice.git] / writerfilter / source / dmapper / SdtHelper.cxx
blob5abccdc86f013058f95e0eeaca3cbb673d812636
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <com/sun/star/awt/Size.hpp>
11 #include <com/sun/star/awt/XControlModel.hpp>
12 #include <com/sun/star/drawing/XControlShape.hpp>
13 #include <com/sun/star/text/VertOrientation.hpp>
15 #include <editeng/unoprnms.hxx>
16 #include <vcl/outdev.hxx>
17 #include <vcl/svapp.hxx>
18 #include <unotools/datetime.hxx>
20 #include <DomainMapper_Impl.hxx>
21 #include <StyleSheetTable.hxx>
22 #include <SdtHelper.hxx>
24 namespace writerfilter
26 namespace dmapper
29 using namespace ::com::sun::star;
31 /// w:sdt's w:dropDownList doesn't have width, so guess the size based on the longest string.
32 awt::Size lcl_getOptimalWidth(StyleSheetTablePtr pStyleSheet, OUString& rDefault, std::vector<OUString>& rItems)
34 OUString aLongest = rDefault;
35 sal_Int32 nHeight = 0;
36 for (size_t i = 0; i < rItems.size(); ++i)
37 if (rItems[i].getLength() > aLongest.getLength())
38 aLongest = rItems[i];
40 MapMode aMap(MAP_100TH_MM);
41 OutputDevice* pOut = Application::GetDefaultDevice();
42 pOut->Push(PUSH_FONT | PUSH_MAPMODE);
44 PropertyMapPtr pDefaultCharProps = pStyleSheet->GetDefaultCharProps();
45 Font aFont(pOut->GetFont());
46 PropertyMap::iterator aFontName = pDefaultCharProps->find(PROP_CHAR_FONT_NAME);
47 if (aFontName != pDefaultCharProps->end())
48 aFont.SetName(aFontName->second.getValue().get<OUString>());
49 PropertyMap::iterator aHeight = pDefaultCharProps->find(PROP_CHAR_HEIGHT);
50 if (aHeight != pDefaultCharProps->end())
52 nHeight = aHeight->second.getValue().get<double>() * 35; // points -> mm100
53 aFont.SetSize(Size(0, nHeight));
55 pOut->SetFont(aFont);
56 pOut->SetMapMode(aMap);
57 sal_Int32 nWidth = pOut->GetTextWidth(aLongest);
59 pOut->Pop();
61 // Border: see PDFWriterImpl::drawFieldBorder(), border size is font height / 4,
62 // so additional width / height needed is height / 2.
63 sal_Int32 nBorder = nHeight / 2;
65 // Width: space for the text + the square having the dropdown arrow.
66 return awt::Size(nWidth + nBorder + nHeight, nHeight + nBorder);
69 SdtHelper::SdtHelper(DomainMapper_Impl& rDM_Impl)
70 : m_rDM_Impl(rDM_Impl)
71 , m_bHasElements(false)
75 SdtHelper::~SdtHelper()
79 void SdtHelper::createDropDownControl()
81 OUString aDefaultText = m_aSdtTexts.makeStringAndClear();
82 uno::Reference<awt::XControlModel> xControlModel(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.form.component.ComboBox"), uno::UNO_QUERY);
83 uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
84 xPropertySet->setPropertyValue("DefaultText", uno::makeAny(aDefaultText));
85 xPropertySet->setPropertyValue("Dropdown", uno::makeAny(sal_True));
86 uno::Sequence<OUString> aItems(m_aDropDownItems.size());
87 for (size_t i = 0; i < m_aDropDownItems.size(); ++i)
88 aItems[i] = m_aDropDownItems[i];
89 xPropertySet->setPropertyValue("StringItemList", uno::makeAny(aItems));
91 createControlShape(lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), aDefaultText, m_aDropDownItems), xControlModel);
92 m_aDropDownItems.clear();
95 void SdtHelper::createDateControl(OUString& rContentText)
97 uno::Reference<awt::XControlModel> xControlModel(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.form.component.DateField"), uno::UNO_QUERY);
98 uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
100 xPropertySet->setPropertyValue("Dropdown", uno::makeAny(sal_True));
102 // See com/sun/star/awt/UnoControlDateFieldModel.idl, DateFormat; sadly there are no constants
103 sal_Int16 nDateFormat = 0;
104 OUString sDateFormat = m_sDateFormat.makeStringAndClear();
105 if (sDateFormat == "M/d/yyyy" || sDateFormat == "M.d.yyyy")
106 // Approximate with MM.dd.yyy
107 nDateFormat = 8;
108 else
109 // Set default format, so at least the date picker is created.
110 SAL_WARN("writerfilter", "unhandled w:dateFormat value");
111 xPropertySet->setPropertyValue("DateFormat", uno::makeAny(nDateFormat));
113 util::Date aDate;
114 util::DateTime aDateTime;
115 if (utl::ISO8601parseDateTime(m_sDate.makeStringAndClear(), aDateTime))
117 utl::extractDate(aDateTime, aDate);
118 xPropertySet->setPropertyValue("Date", uno::makeAny(aDate));
119 xPropertySet->setPropertyValue("HelpText", uno::makeAny(OUString("Click here to enter a date")));
121 else
122 xPropertySet->setPropertyValue("HelpText", uno::makeAny(rContentText));
124 // append date format to grab bag
125 uno::Sequence<beans::PropertyValue> aGrabBag(4);
126 aGrabBag[0].Name = "OriginalDate";
127 aGrabBag[0].Value = uno::makeAny(aDate);
128 aGrabBag[1].Name = "OriginalContent";
129 aGrabBag[1].Value = uno::makeAny(rContentText);
130 aGrabBag[2].Name = "DateFormat";
131 aGrabBag[2].Value = uno::makeAny(sDateFormat);
132 aGrabBag[3].Name = "Locale";
133 aGrabBag[3].Value = uno::makeAny(m_sLocale.makeStringAndClear());
135 std::vector<OUString> aItems;
136 createControlShape(lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), rContentText, aItems), xControlModel, aGrabBag);
139 void SdtHelper::createControlShape(awt::Size aSize, uno::Reference<awt::XControlModel> xControlModel)
141 createControlShape(aSize, xControlModel, uno::Sequence<beans::PropertyValue>());
144 void SdtHelper::createControlShape(awt::Size aSize, uno::Reference<awt::XControlModel> xControlModel, const uno::Sequence<beans::PropertyValue>& rGrabBag)
146 uno::Reference<drawing::XControlShape> xControlShape(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.drawing.ControlShape"), uno::UNO_QUERY);
147 xControlShape->setSize(aSize);
148 xControlShape->setControl(xControlModel);
150 uno::Reference<beans::XPropertySet> xPropertySet(xControlShape, uno::UNO_QUERY);
151 xPropertySet->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::CENTER));
153 if (rGrabBag.hasElements())
154 xPropertySet->setPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG, uno::makeAny(rGrabBag));
156 uno::Reference<text::XTextContent> xTextContent(xControlShape, uno::UNO_QUERY);
157 m_rDM_Impl.appendTextContent(xTextContent, uno::Sequence< beans::PropertyValue >());
158 m_bHasElements = true;
161 std::vector<OUString>& SdtHelper::getDropDownItems()
163 return m_aDropDownItems;
166 OUStringBuffer& SdtHelper::getSdtTexts()
168 return m_aSdtTexts;
171 OUStringBuffer& SdtHelper::getDate()
173 return m_sDate;
176 OUStringBuffer& SdtHelper::getDateFormat()
178 return m_sDateFormat;
181 OUStringBuffer& SdtHelper::getLocale()
183 return m_sLocale;
186 bool SdtHelper::hasElements()
188 return m_bHasElements;
191 void SdtHelper::appendToInteropGrabBag(com::sun::star::beans::PropertyValue rValue)
193 sal_Int32 nLength = m_aGrabBag.getLength();
194 m_aGrabBag.realloc(nLength + 1);
195 m_aGrabBag[nLength] = rValue;
198 com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> SdtHelper::getInteropGrabBagAndClear()
200 com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> aRet = m_aGrabBag;
201 m_aGrabBag.realloc(0);
202 return aRet;
205 bool SdtHelper::isInteropGrabBagEmpty()
207 return m_aGrabBag.getLength() == 0;
210 sal_Int32 SdtHelper::getInteropGrabBagSize()
212 return m_aGrabBag.getLength();
215 bool SdtHelper::containedInInteropGrabBag(const OUString& rValueName)
217 for (sal_Int32 i=0; i < m_aGrabBag.getLength(); ++i)
218 if (m_aGrabBag[i].Name == rValueName)
219 return true;
221 return false;
224 } // namespace dmapper
225 } // namespace writerfilter
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */