Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
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>
14 :
15 : #include <editeng/unoprnms.hxx>
16 : #include <vcl/outdev.hxx>
17 : #include <vcl/svapp.hxx>
18 : #include <unotools/datetime.hxx>
19 :
20 : #include <DomainMapper_Impl.hxx>
21 : #include <StyleSheetTable.hxx>
22 : #include <SdtHelper.hxx>
23 :
24 : namespace writerfilter
25 : {
26 : namespace dmapper
27 : {
28 :
29 : using namespace ::com::sun::star;
30 :
31 : /// w:sdt's w:dropDownList doesn't have width, so guess the size based on the longest string.
32 15 : awt::Size lcl_getOptimalWidth(StyleSheetTablePtr pStyleSheet, OUString& rDefault, std::vector<OUString>& rItems)
33 : {
34 15 : OUString aLongest = rDefault;
35 15 : sal_Int32 nHeight = 0;
36 23 : for (size_t i = 0; i < rItems.size(); ++i)
37 8 : if (rItems[i].getLength() > aLongest.getLength())
38 0 : aLongest = rItems[i];
39 :
40 30 : MapMode aMap(MAP_100TH_MM);
41 15 : OutputDevice* pOut = Application::GetDefaultDevice();
42 15 : pOut->Push(PUSH_FONT | PUSH_MAPMODE);
43 :
44 30 : PropertyMapPtr pDefaultCharProps = pStyleSheet->GetDefaultCharProps();
45 30 : Font aFont(pOut->GetFont());
46 15 : PropertyMap::iterator aFontName = pDefaultCharProps->find(PROP_CHAR_FONT_NAME);
47 15 : if (aFontName != pDefaultCharProps->end())
48 15 : aFont.SetName(aFontName->second.getValue().get<OUString>());
49 15 : PropertyMap::iterator aHeight = pDefaultCharProps->find(PROP_CHAR_HEIGHT);
50 15 : if (aHeight != pDefaultCharProps->end())
51 : {
52 15 : nHeight = aHeight->second.getValue().get<double>() * 35; // points -> mm100
53 15 : aFont.SetSize(Size(0, nHeight));
54 : }
55 15 : pOut->SetFont(aFont);
56 15 : pOut->SetMapMode(aMap);
57 15 : sal_Int32 nWidth = pOut->GetTextWidth(aLongest);
58 :
59 15 : pOut->Pop();
60 :
61 : // Border: see PDFWriterImpl::drawFieldBorder(), border size is font height / 4,
62 : // so additional width / height needed is height / 2.
63 15 : sal_Int32 nBorder = nHeight / 2;
64 :
65 : // Width: space for the text + the square having the dropdown arrow.
66 30 : return awt::Size(nWidth + nBorder + nHeight, nHeight + nBorder);
67 : }
68 :
69 1191 : SdtHelper::SdtHelper(DomainMapper_Impl& rDM_Impl)
70 : : m_rDM_Impl(rDM_Impl)
71 1191 : , m_bHasElements(false)
72 : {
73 1191 : }
74 :
75 2382 : SdtHelper::~SdtHelper()
76 : {
77 2382 : }
78 :
79 4 : void SdtHelper::createDropDownControl()
80 : {
81 4 : OUString aDefaultText = m_aSdtTexts.makeStringAndClear();
82 8 : uno::Reference<awt::XControlModel> xControlModel(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.form.component.ComboBox"), uno::UNO_QUERY);
83 8 : uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
84 4 : xPropertySet->setPropertyValue("DefaultText", uno::makeAny(aDefaultText));
85 4 : xPropertySet->setPropertyValue("Dropdown", uno::makeAny(sal_True));
86 8 : uno::Sequence<OUString> aItems(m_aDropDownItems.size());
87 12 : for (size_t i = 0; i < m_aDropDownItems.size(); ++i)
88 8 : aItems[i] = m_aDropDownItems[i];
89 4 : xPropertySet->setPropertyValue("StringItemList", uno::makeAny(aItems));
90 :
91 4 : createControlShape(lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), aDefaultText, m_aDropDownItems), xControlModel);
92 8 : m_aDropDownItems.clear();
93 4 : }
94 :
95 11 : void SdtHelper::createDateControl(OUString& rContentText)
96 : {
97 11 : uno::Reference<awt::XControlModel> xControlModel(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.form.component.DateField"), uno::UNO_QUERY);
98 22 : uno::Reference<beans::XPropertySet> xPropertySet(xControlModel, uno::UNO_QUERY);
99 :
100 11 : xPropertySet->setPropertyValue("Dropdown", uno::makeAny(sal_True));
101 :
102 : // See com/sun/star/awt/UnoControlDateFieldModel.idl, DateFormat; sadly there are no constants
103 11 : sal_Int16 nDateFormat = 0;
104 22 : OUString sDateFormat = m_sDateFormat.makeStringAndClear();
105 11 : if (sDateFormat == "M/d/yyyy" || sDateFormat == "M.d.yyyy")
106 : // Approximate with MM.dd.yyy
107 4 : 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 11 : xPropertySet->setPropertyValue("DateFormat", uno::makeAny(nDateFormat));
112 :
113 11 : util::Date aDate;
114 11 : util::DateTime aDateTime;
115 11 : if (utl::ISO8601parseDateTime(m_sDate.makeStringAndClear(), aDateTime))
116 : {
117 8 : utl::extractDate(aDateTime, aDate);
118 8 : xPropertySet->setPropertyValue("Date", uno::makeAny(aDate));
119 8 : xPropertySet->setPropertyValue("HelpText", uno::makeAny(OUString("Click here to enter a date")));
120 : }
121 : else
122 3 : xPropertySet->setPropertyValue("HelpText", uno::makeAny(rContentText));
123 :
124 : // append date format to grab bag
125 22 : uno::Sequence<beans::PropertyValue> aGrabBag(4);
126 11 : aGrabBag[0].Name = "OriginalDate";
127 11 : aGrabBag[0].Value = uno::makeAny(aDate);
128 11 : aGrabBag[1].Name = "OriginalContent";
129 11 : aGrabBag[1].Value = uno::makeAny(rContentText);
130 11 : aGrabBag[2].Name = "DateFormat";
131 11 : aGrabBag[2].Value = uno::makeAny(sDateFormat);
132 11 : aGrabBag[3].Name = "Locale";
133 11 : aGrabBag[3].Value = uno::makeAny(m_sLocale.makeStringAndClear());
134 :
135 22 : std::vector<OUString> aItems;
136 22 : createControlShape(lcl_getOptimalWidth(m_rDM_Impl.GetStyleSheetTable(), rContentText, aItems), xControlModel, aGrabBag);
137 11 : }
138 :
139 4 : void SdtHelper::createControlShape(awt::Size aSize, uno::Reference<awt::XControlModel> xControlModel)
140 : {
141 4 : createControlShape(aSize, xControlModel, uno::Sequence<beans::PropertyValue>());
142 4 : }
143 :
144 15 : void SdtHelper::createControlShape(awt::Size aSize, uno::Reference<awt::XControlModel> xControlModel, uno::Sequence<beans::PropertyValue> rGrabBag)
145 : {
146 15 : uno::Reference<drawing::XControlShape> xControlShape(m_rDM_Impl.GetTextFactory()->createInstance("com.sun.star.drawing.ControlShape"), uno::UNO_QUERY);
147 15 : xControlShape->setSize(aSize);
148 15 : xControlShape->setControl(xControlModel);
149 :
150 30 : uno::Reference<beans::XPropertySet> xPropertySet(xControlShape, uno::UNO_QUERY);
151 15 : xPropertySet->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::CENTER));
152 :
153 15 : if (rGrabBag.hasElements())
154 11 : xPropertySet->setPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG, uno::makeAny(rGrabBag));
155 :
156 30 : uno::Reference<text::XTextContent> xTextContent(xControlShape, uno::UNO_QUERY);
157 15 : m_rDM_Impl.appendTextContent(xTextContent, uno::Sequence< beans::PropertyValue >());
158 30 : m_bHasElements = true;
159 15 : }
160 :
161 59166 : std::vector<OUString>& SdtHelper::getDropDownItems()
162 : {
163 59166 : return m_aDropDownItems;
164 : }
165 :
166 6 : OUStringBuffer& SdtHelper::getSdtTexts()
167 : {
168 6 : return m_aSdtTexts;
169 : }
170 :
171 8 : OUStringBuffer& SdtHelper::getDate()
172 : {
173 8 : return m_sDate;
174 : }
175 :
176 58969 : OUStringBuffer& SdtHelper::getDateFormat()
177 : {
178 58969 : return m_sDateFormat;
179 : }
180 :
181 11 : OUStringBuffer& SdtHelper::getLocale()
182 : {
183 11 : return m_sLocale;
184 : }
185 :
186 1201 : bool SdtHelper::hasElements()
187 : {
188 1201 : return m_bHasElements;
189 : }
190 :
191 0 : void SdtHelper::appendToInteropGrabBag(const OUString& rName, const css::uno::Any& rValue)
192 : {
193 0 : sal_Int32 nLength = m_aGrabBag.getLength();
194 0 : m_aGrabBag.realloc(nLength + 1);
195 0 : m_aGrabBag[nLength].Name = rName;
196 0 : m_aGrabBag[nLength].Value = rValue;
197 0 : }
198 :
199 341 : void SdtHelper::appendToInteropGrabBag(com::sun::star::beans::PropertyValue rValue)
200 : {
201 341 : sal_Int32 nLength = m_aGrabBag.getLength();
202 341 : m_aGrabBag.realloc(nLength + 1);
203 341 : m_aGrabBag[nLength] = rValue;
204 341 : }
205 :
206 188 : com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> SdtHelper::getInteropGrabBagAndClear()
207 : {
208 188 : com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> aRet = m_aGrabBag;
209 188 : m_aGrabBag.realloc(0);
210 188 : return aRet;
211 : }
212 :
213 58947 : bool SdtHelper::isInteropGrabBagEmpty()
214 : {
215 58947 : return m_aGrabBag.getLength() == 0;
216 : }
217 :
218 111 : sal_Int32 SdtHelper::getInteropGrabBagSize()
219 : {
220 111 : return m_aGrabBag.getLength();
221 : }
222 :
223 671 : bool SdtHelper::containedInInteropGrabBag(const OUString& rValueName)
224 : {
225 1576 : for (sal_Int32 i=0; i < m_aGrabBag.getLength(); ++i)
226 1058 : if (m_aGrabBag[i].Name == rValueName)
227 153 : return true;
228 :
229 518 : return false;
230 : }
231 :
232 : } // namespace dmapper
233 : } // namespace writerfilter
234 :
235 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|