1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include <math.h>
25
26 #include <com/sun/star/awt/XControlModel.hpp>
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/container/XIndexContainer.hpp>
29 #include <com/sun/star/drawing/XControlShape.hpp>
30 #include <com/sun/star/drawing/XDrawPage.hpp>
31 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
32 #include <com/sun/star/form/XForm.hpp>
33 #include <com/sun/star/form/XFormComponent.hpp>
34 #include <com/sun/star/form/XFormsSupplier.hpp>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 #include <com/sun/star/text/TextContentAnchorType.hpp>
37 #include <com/sun/star/text/VertOrientation.hpp>
38 #include <com/sun/star/uno/Any.hxx>
39 #include <com/sun/star/uno/Type.hxx>
40
41 #include "FormControlHelper.hxx"
42
43 namespace writerfilter {
44 namespace dmapper {
45
46 using namespace ::com::sun::star;
47
48 struct FormControlHelper::FormControlHelper_Impl
49 {
50 FieldId m_eFieldId;
51 awt::Size aSize;
52 uno::Reference<drawing::XDrawPage> rDrawPage;
53 uno::Reference<form::XForm> rForm;
54 uno::Reference<form::XFormComponent> rFormComponent;
55 uno::Reference<lang::XMultiServiceFactory> rServiceFactory;
56 uno::Reference<text::XTextDocument> rTextDocument;
57
58 uno::Reference<drawing::XDrawPage> getDrawPage();
59 uno::Reference<lang::XMultiServiceFactory> getServiceFactory();
60 uno::Reference<form::XForm> getForm();
61 uno::Reference<container::XIndexContainer> getFormComps();
62 };
63
getDrawPage()64 uno::Reference<drawing::XDrawPage> FormControlHelper::FormControlHelper_Impl::getDrawPage()
65 {
66 if (! rDrawPage.is())
67 {
68 uno::Reference<drawing::XDrawPageSupplier>
69 xDrawPageSupplier(rTextDocument, uno::UNO_QUERY);
70 if (xDrawPageSupplier.is())
71 rDrawPage = xDrawPageSupplier->getDrawPage();
72 }
73
74 return rDrawPage;
75 }
76
getServiceFactory()77 uno::Reference<lang::XMultiServiceFactory> FormControlHelper::FormControlHelper_Impl::getServiceFactory()
78 {
79 if (! rServiceFactory.is())
80 rServiceFactory = uno::Reference<lang::XMultiServiceFactory>(rTextDocument, uno::UNO_QUERY);
81
82 return rServiceFactory;
83 }
84
getForm()85 uno::Reference<form::XForm> FormControlHelper::FormControlHelper_Impl::getForm()
86 {
87 if (! rForm.is())
88 {
89 uno::Reference<form::XFormsSupplier> xFormsSupplier(getDrawPage(), uno::UNO_QUERY);
90
91 if (xFormsSupplier.is())
92 {
93 uno::Reference<container::XNameContainer> xFormsNamedContainer(xFormsSupplier->getForms());
94 static ::rtl::OUString sDOCXForm(RTL_CONSTASCII_USTRINGPARAM("DOCX-Standard"));
95
96 ::rtl::OUString sFormName(sDOCXForm);
97 sal_uInt16 nUnique = 0;
98
99 while (xFormsNamedContainer->hasByName(sFormName))
100 {
101 ++nUnique;
102 sFormName = sDOCXForm;
103 sFormName += ::rtl::OUString::valueOf(nUnique);
104 }
105
106 uno::Reference<uno::XInterface>
107 xForm(getServiceFactory()->createInstance
108 (::rtl::OUString
109 (RTL_CONSTASCII_USTRINGPARAM
110 ("com.sun.star.form.component.Form"))));
111 if (xForm.is())
112 {
113 uno::Reference<beans::XPropertySet>
114 xFormProperties(xForm, uno::UNO_QUERY);
115 uno::Any aAny(sFormName);
116 static ::rtl::OUString sName(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name")));
117 xFormProperties->setPropertyValue(sName, aAny);
118 }
119
120 rForm = uno::Reference<form::XForm>(xForm, uno::UNO_QUERY);
121
122 uno::Reference<container::XIndexContainer> xForms(xFormsNamedContainer, uno::UNO_QUERY);
123 uno::Any aAny(xForm);
124 xForms->insertByIndex(xForms->getCount(), aAny);
125 }
126 }
127
128 return rForm;
129 }
130
getFormComps()131 uno::Reference<container::XIndexContainer> FormControlHelper::FormControlHelper_Impl::getFormComps()
132 {
133 uno::Reference<container::XIndexContainer> xIndexContainer(getForm(), uno::UNO_QUERY);
134
135 return xIndexContainer;
136 }
137
FormControlHelper(FieldId eFieldId,uno::Reference<text::XTextDocument> rTextDocument,FFDataHandler::Pointer_t pFFData)138 FormControlHelper::FormControlHelper(FieldId eFieldId,
139 uno::Reference<text::XTextDocument> rTextDocument,
140 FFDataHandler::Pointer_t pFFData)
141 : m_pFFData(pFFData), m_pImpl(new FormControlHelper_Impl)
142 {
143 m_pImpl->m_eFieldId = eFieldId;
144 m_pImpl->rTextDocument = rTextDocument;
145 }
146
~FormControlHelper()147 FormControlHelper::~FormControlHelper()
148 {
149 }
150
createCheckbox(uno::Reference<text::XTextRange> xTextRange,const::rtl::OUString & rControlName)151 bool FormControlHelper::createCheckbox(uno::Reference<text::XTextRange> xTextRange,
152 const ::rtl::OUString & rControlName)
153 {
154 uno::Reference<lang::XMultiServiceFactory>
155 xServiceFactory(m_pImpl->getServiceFactory());
156
157 if (! xServiceFactory.is())
158 return false;
159
160 uno::Reference<uno::XInterface> xInterface =
161 xServiceFactory->createInstance
162 (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.component.CheckBox")));
163
164 if (!xInterface.is())
165 return false;
166
167 m_pImpl->rFormComponent = uno::Reference<form::XFormComponent>(xInterface, uno::UNO_QUERY);
168 if (!m_pImpl->rFormComponent.is())
169 return false;
170
171 uno::Reference<beans::XPropertySet> xPropSet(xInterface, uno::UNO_QUERY);
172
173 sal_uInt32 nCheckBoxHeight = 16 * m_pFFData->getCheckboxHeight();
174
175 if (m_pFFData->getCheckboxAutoHeight())
176 {
177 uno::Reference<beans::XPropertySet> xTextRangeProps(xTextRange, uno::UNO_QUERY);
178
179 try
180 {
181 static ::rtl::OUString sCharHeight(RTL_CONSTASCII_USTRINGPARAM("CharHeight"));
182 float fCheckBoxHeight = 0.0;
183 xTextRangeProps->getPropertyValue(sCharHeight) >>= fCheckBoxHeight;
184 nCheckBoxHeight = floor(fCheckBoxHeight * 35.3);
185 }
186 catch (beans::UnknownPropertyException & rException)
187 {
188 (void) rException;
189 }
190 }
191
192 m_pImpl->aSize.Width = nCheckBoxHeight;
193 m_pImpl->aSize.Height = m_pImpl->aSize.Width;
194
195 uno::Any aAny;
196 if (m_pFFData->getStatusText().getLength())
197 {
198 aAny <<= m_pFFData->getStatusText();
199
200 xPropSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HelpText")), aAny);
201 }
202
203 aAny <<= m_pFFData->getCheckboxChecked();
204 xPropSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultState")), aAny);
205
206 if (m_pFFData->getHelpText().getLength())
207 {
208 aAny <<= m_pFFData->getHelpText();
209 xPropSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HelpF1Text")), aAny);
210 }
211
212 aAny <<= rControlName;
213 xPropSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name")), aAny);
214
215 return true;
216 }
217
insertControl(uno::Reference<text::XTextRange> xTextRange)218 bool FormControlHelper::insertControl(uno::Reference<text::XTextRange> xTextRange)
219 {
220 bool bCreated = false;
221
222 uno::Reference<container::XNameContainer> xFormCompsByName(m_pImpl->getForm(), uno::UNO_QUERY);
223 uno::Reference<container::XIndexContainer> xFormComps(m_pImpl->getFormComps());
224 if (! xFormComps.is())
225 return false;
226
227 static ::rtl::OUString sControl(RTL_CONSTASCII_USTRINGPARAM("Control"));
228
229 sal_Int32 nControl = 0;
230 bool bDone = false;
231 ::rtl::OUString sControlName;
232
233 do
234 {
235 ::rtl::OUString sTmp(sControl);
236 sTmp += ::rtl::OUString::valueOf(nControl);
237
238 nControl++;
239 if (! xFormCompsByName->hasByName(sTmp))
240 {
241 sControlName = sTmp;
242 bDone = true;
243 }
244 }
245 while (! bDone);
246
247 switch (m_pImpl->m_eFieldId)
248 {
249 case FIELD_FORMCHECKBOX:
250 bCreated = createCheckbox(xTextRange, sControlName);
251 break;
252 default:
253 break;
254 }
255
256 if (!bCreated)
257 return false;
258
259 uno::Any aAny(m_pImpl->rFormComponent);
260 xFormComps->insertByIndex(xFormComps->getCount(), aAny);
261
262 if (! m_pImpl->getServiceFactory().is())
263 return false;
264
265 uno::Reference<uno::XInterface> xInterface =
266 m_pImpl->getServiceFactory()->createInstance
267 (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.ControlShape")));
268
269 if (! xInterface.is())
270 return false;
271
272 uno::Reference<drawing::XShape> xShape(xInterface, uno::UNO_QUERY);
273
274 if (! xShape.is())
275 return false;
276
277 xShape->setSize(m_pImpl->aSize);
278
279 uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
280
281 sal_uInt16 nTmp = text::TextContentAnchorType_AS_CHARACTER;
282 aAny <<= nTmp;
283
284 static const ::rtl::OUString sAnchorType(RTL_CONSTASCII_USTRINGPARAM("AnchorType"));
285 xShapeProps->setPropertyValue(sAnchorType, aAny);
286
287 static const ::rtl::OUString sVertOrient(RTL_CONSTASCII_USTRINGPARAM("VertOrient"));
288 nTmp = text::VertOrientation::CENTER;
289 aAny <<= nTmp;
290 xShapeProps->setPropertyValue(sVertOrient, aAny);
291
292 aAny <<= xTextRange;
293
294 static const ::rtl::OUString sTextRange(RTL_CONSTASCII_USTRINGPARAM("TextRange"));
295 xShapeProps->setPropertyValue(sTextRange, aAny);
296
297 uno::Reference<drawing::XControlShape> xControlShape(xShape, uno::UNO_QUERY);
298 uno::Reference<awt::XControlModel> xControlModel(m_pImpl->rFormComponent, uno::UNO_QUERY);
299 xControlShape->setControl(xControlModel);
300
301 m_pImpl->getDrawPage()->add(xShape);
302
303 return true;
304 }
305
306 }}
307