1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <com/sun/star/awt/XControlModel.hpp>
23 #include <com/sun/star/beans/XPropertySet.hpp>
24 #include <com/sun/star/container/XIndexContainer.hpp>
25 #include <com/sun/star/container/XNamed.hpp>
26 #include <com/sun/star/drawing/XControlShape.hpp>
27 #include <com/sun/star/drawing/XDrawPage.hpp>
28 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
29 #include <com/sun/star/form/XForm.hpp>
30 #include <com/sun/star/form/XFormComponent.hpp>
31 #include <com/sun/star/form/XFormsSupplier.hpp>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/text/TextContentAnchorType.hpp>
34 #include <com/sun/star/text/VertOrientation.hpp>
35 #include <com/sun/star/uno/Any.hxx>
36 #include <com/sun/star/uno/Type.hxx>
38 #include "FormControlHelper.hxx"
39 #include <xmloff/odffields.hxx>
40 #include <comphelper/stlunosequence.hxx>
42 namespace writerfilter
{
45 using namespace ::com::sun::star
;
47 struct FormControlHelper::FormControlHelper_Impl
51 uno::Reference
<drawing::XDrawPage
> rDrawPage
;
52 uno::Reference
<form::XForm
> rForm
;
53 uno::Reference
<form::XFormComponent
> rFormComponent
;
54 uno::Reference
<lang::XMultiServiceFactory
> rServiceFactory
;
55 uno::Reference
<text::XTextDocument
> rTextDocument
;
57 uno::Reference
<drawing::XDrawPage
> getDrawPage();
58 uno::Reference
<lang::XMultiServiceFactory
> getServiceFactory();
59 uno::Reference
<form::XForm
> getForm();
60 uno::Reference
<container::XIndexContainer
> getFormComps();
63 uno::Reference
<drawing::XDrawPage
> FormControlHelper::FormControlHelper_Impl::getDrawPage()
67 uno::Reference
<drawing::XDrawPageSupplier
>
68 xDrawPageSupplier(rTextDocument
, uno::UNO_QUERY
);
69 if (xDrawPageSupplier
.is())
70 rDrawPage
= xDrawPageSupplier
->getDrawPage();
76 uno::Reference
<lang::XMultiServiceFactory
> FormControlHelper::FormControlHelper_Impl::getServiceFactory()
78 if (! rServiceFactory
.is())
79 rServiceFactory
= uno::Reference
<lang::XMultiServiceFactory
>(rTextDocument
, uno::UNO_QUERY
);
81 return rServiceFactory
;
84 uno::Reference
<form::XForm
> FormControlHelper::FormControlHelper_Impl::getForm()
88 uno::Reference
<form::XFormsSupplier
> xFormsSupplier(getDrawPage(), uno::UNO_QUERY
);
90 if (xFormsSupplier
.is())
92 uno::Reference
<container::XNameContainer
> xFormsNamedContainer(xFormsSupplier
->getForms());
93 static OUString
sDOCXForm("DOCX-Standard");
95 OUString
sFormName(sDOCXForm
);
96 sal_uInt16 nUnique
= 0;
98 while (xFormsNamedContainer
->hasByName(sFormName
))
101 sFormName
= sDOCXForm
;
102 sFormName
+= OUString::valueOf(nUnique
);
105 uno::Reference
<uno::XInterface
> xForm(getServiceFactory()->createInstance("com.sun.star.form.component.Form"));
108 uno::Reference
<beans::XPropertySet
>
109 xFormProperties(xForm
, uno::UNO_QUERY
);
110 uno::Any
aAny(sFormName
);
111 xFormProperties
->setPropertyValue("Name", aAny
);
114 rForm
= uno::Reference
<form::XForm
>(xForm
, uno::UNO_QUERY
);
116 uno::Reference
<container::XIndexContainer
> xForms(xFormsNamedContainer
, uno::UNO_QUERY
);
117 uno::Any
aAny(xForm
);
118 xForms
->insertByIndex(xForms
->getCount(), aAny
);
125 uno::Reference
<container::XIndexContainer
> FormControlHelper::FormControlHelper_Impl::getFormComps()
127 uno::Reference
<container::XIndexContainer
> xIndexContainer(getForm(), uno::UNO_QUERY
);
129 return xIndexContainer
;
132 FormControlHelper::FormControlHelper(FieldId eFieldId
,
133 uno::Reference
<text::XTextDocument
> rTextDocument
,
134 FFDataHandler::Pointer_t pFFData
)
135 : m_pFFData(pFFData
), m_pImpl(new FormControlHelper_Impl
)
137 m_pImpl
->m_eFieldId
= eFieldId
;
138 m_pImpl
->rTextDocument
= rTextDocument
;
141 FormControlHelper::~FormControlHelper()
145 bool FormControlHelper::createCheckbox(uno::Reference
<text::XTextRange
> xTextRange
,
146 const OUString
& rControlName
)
150 uno::Reference
<lang::XMultiServiceFactory
>
151 xServiceFactory(m_pImpl
->getServiceFactory());
153 if (! xServiceFactory
.is())
156 uno::Reference
<uno::XInterface
> xInterface
= xServiceFactory
->createInstance("com.sun.star.form.component.CheckBox");
158 if (!xInterface
.is())
161 m_pImpl
->rFormComponent
= uno::Reference
<form::XFormComponent
>(xInterface
, uno::UNO_QUERY
);
162 if (!m_pImpl
->rFormComponent
.is())
165 uno::Reference
<beans::XPropertySet
> xPropSet(xInterface
, uno::UNO_QUERY
);
167 sal_uInt32 nCheckBoxHeight
= 16 * m_pFFData
->getCheckboxHeight();
169 if (m_pFFData
->getCheckboxAutoHeight())
171 uno::Reference
<beans::XPropertySet
> xTextRangeProps(xTextRange
, uno::UNO_QUERY
);
175 float fCheckBoxHeight
= 0.0;
176 xTextRangeProps
->getPropertyValue("CharHeight") >>= fCheckBoxHeight
;
177 nCheckBoxHeight
= static_cast<sal_uInt32
>(floor(fCheckBoxHeight
* 35.3));
179 catch (beans::UnknownPropertyException
&)
184 m_pImpl
->aSize
.Width
= nCheckBoxHeight
;
185 m_pImpl
->aSize
.Height
= m_pImpl
->aSize
.Width
;
188 if (!m_pFFData
->getStatusText().isEmpty())
190 aAny
<<= m_pFFData
->getStatusText();
192 xPropSet
->setPropertyValue("HelpText", aAny
);
195 aAny
<<= m_pFFData
->getCheckboxChecked();
196 xPropSet
->setPropertyValue("DefaultState", aAny
);
198 if (!m_pFFData
->getHelpText().isEmpty())
200 aAny
<<= m_pFFData
->getHelpText();
201 xPropSet
->setPropertyValue("HelpF1Text", aAny
);
204 aAny
<<= rControlName
;
205 xPropSet
->setPropertyValue("Name", aAny
);
210 bool FormControlHelper::processField(uno::Reference
<text::XFormField
> xFormField
)
213 uno::Reference
<container::XNameContainer
> xNameCont
= xFormField
->getParameters();
214 uno::Reference
<container::XNamed
> xNamed( xFormField
, uno::UNO_QUERY
);
215 if ( m_pFFData
&& xNamed
.is() && xNameCont
.is() )
218 if (m_pImpl
->m_eFieldId
== FIELD_FORMTEXT
)
220 xFormField
->setFieldType(ODF_FORMTEXT
);
221 if ( !m_pFFData
->getName().isEmpty() )
223 xNamed
->setName( m_pFFData
->getName() );
226 else if (m_pImpl
->m_eFieldId
== FIELD_FORMCHECKBOX
)
228 xFormField
->setFieldType(ODF_FORMCHECKBOX
);
229 uno::Reference
<beans::XPropertySet
> xPropSet(xFormField
, uno::UNO_QUERY
);
231 aAny
<<= m_pFFData
->getCheckboxChecked();
233 xPropSet
->setPropertyValue("Checked", aAny
);
235 else if (m_pImpl
->m_eFieldId
== FIELD_FORMDROPDOWN
)
237 xFormField
->setFieldType(ODF_FORMDROPDOWN
);
238 uno::Sequence
< OUString
> sItems
;
239 sItems
.realloc( m_pFFData
->getDropDownEntries().size() );
240 ::std::copy( m_pFFData
->getDropDownEntries().begin(), m_pFFData
->getDropDownEntries().end(), ::comphelper::stl_begin(sItems
));
241 if ( sItems
.getLength() )
243 if ( xNameCont
->hasByName(ODF_FORMDROPDOWN_LISTENTRY
) )
244 xNameCont
->replaceByName(ODF_FORMDROPDOWN_LISTENTRY
, uno::makeAny( sItems
) );
246 xNameCont
->insertByName(ODF_FORMDROPDOWN_LISTENTRY
, uno::makeAny( sItems
) );
248 sal_Int32 nResult
= m_pFFData
->getDropDownResult().toInt32();
251 if ( xNameCont
->hasByName(ODF_FORMDROPDOWN_RESULT
) )
252 xNameCont
->replaceByName(ODF_FORMDROPDOWN_RESULT
, uno::makeAny( nResult
) );
254 xNameCont
->insertByName(ODF_FORMDROPDOWN_RESULT
, uno::makeAny( nResult
) );
264 bool FormControlHelper::insertControl(uno::Reference
<text::XTextRange
> xTextRange
)
266 bool bCreated
= false;
269 uno::Reference
<container::XNameContainer
> xFormCompsByName(m_pImpl
->getForm(), uno::UNO_QUERY
);
270 uno::Reference
<container::XIndexContainer
> xFormComps(m_pImpl
->getFormComps());
271 if (! xFormComps
.is())
274 static OUString
sControl("Control");
276 sal_Int32 nControl
= 0;
278 OUString sControlName
;
282 OUString
sTmp(sControl
);
283 sTmp
+= OUString::valueOf(nControl
);
286 if (! xFormCompsByName
->hasByName(sTmp
))
294 switch (m_pImpl
->m_eFieldId
)
296 case FIELD_FORMCHECKBOX
:
297 bCreated
= createCheckbox(xTextRange
, sControlName
);
306 uno::Any
aAny(m_pImpl
->rFormComponent
);
307 xFormComps
->insertByIndex(xFormComps
->getCount(), aAny
);
309 if (! m_pImpl
->getServiceFactory().is())
312 uno::Reference
<uno::XInterface
> xInterface
= m_pImpl
->getServiceFactory()->createInstance("com.sun.star.drawing.ControlShape");
314 if (! xInterface
.is())
317 uno::Reference
<drawing::XShape
> xShape(xInterface
, uno::UNO_QUERY
);
322 xShape
->setSize(m_pImpl
->aSize
);
324 uno::Reference
<beans::XPropertySet
> xShapeProps(xShape
, uno::UNO_QUERY
);
326 sal_uInt16 nTmp
= text::TextContentAnchorType_AS_CHARACTER
;
329 xShapeProps
->setPropertyValue("AnchorType", aAny
);
331 nTmp
= text::VertOrientation::CENTER
;
333 xShapeProps
->setPropertyValue("VertOrient", aAny
);
337 xShapeProps
->setPropertyValue("TextRange", aAny
);
339 uno::Reference
<drawing::XControlShape
> xControlShape(xShape
, uno::UNO_QUERY
);
340 uno::Reference
<awt::XControlModel
> xControlModel(m_pImpl
->rFormComponent
, uno::UNO_QUERY
);
341 xControlShape
->setControl(xControlModel
);
343 m_pImpl
->getDrawPage()->add(xShape
);
350 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */