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>
41 namespace writerfilter
{
44 using namespace ::com::sun::star
;
46 struct FormControlHelper::FormControlHelper_Impl
50 uno::Reference
<drawing::XDrawPage
> rDrawPage
;
51 uno::Reference
<form::XForm
> rForm
;
52 uno::Reference
<form::XFormComponent
> rFormComponent
;
53 uno::Reference
<lang::XMultiServiceFactory
> rServiceFactory
;
54 uno::Reference
<text::XTextDocument
> rTextDocument
;
56 uno::Reference
<drawing::XDrawPage
> getDrawPage();
57 uno::Reference
<lang::XMultiServiceFactory
> getServiceFactory();
58 uno::Reference
<form::XForm
> getForm();
59 uno::Reference
<container::XIndexContainer
> getFormComps();
62 uno::Reference
<drawing::XDrawPage
> FormControlHelper::FormControlHelper_Impl::getDrawPage()
66 uno::Reference
<drawing::XDrawPageSupplier
>
67 xDrawPageSupplier(rTextDocument
, uno::UNO_QUERY
);
68 if (xDrawPageSupplier
.is())
69 rDrawPage
= xDrawPageSupplier
->getDrawPage();
75 uno::Reference
<lang::XMultiServiceFactory
> FormControlHelper::FormControlHelper_Impl::getServiceFactory()
77 if (! rServiceFactory
.is())
78 rServiceFactory
= uno::Reference
<lang::XMultiServiceFactory
>(rTextDocument
, uno::UNO_QUERY
);
80 return rServiceFactory
;
83 uno::Reference
<form::XForm
> FormControlHelper::FormControlHelper_Impl::getForm()
87 uno::Reference
<form::XFormsSupplier
> xFormsSupplier(getDrawPage(), uno::UNO_QUERY
);
89 if (xFormsSupplier
.is())
91 uno::Reference
<container::XNameContainer
> xFormsNamedContainer(xFormsSupplier
->getForms());
92 static OUString
sDOCXForm("DOCX-Standard");
94 OUString
sFormName(sDOCXForm
);
95 sal_uInt16 nUnique
= 0;
97 while (xFormsNamedContainer
->hasByName(sFormName
))
100 sFormName
= sDOCXForm
;
101 sFormName
+= OUString(nUnique
);
104 uno::Reference
<uno::XInterface
> xForm(getServiceFactory()->createInstance("com.sun.star.form.component.Form"));
107 uno::Reference
<beans::XPropertySet
>
108 xFormProperties(xForm
, uno::UNO_QUERY
);
109 uno::Any
aAny(sFormName
);
110 xFormProperties
->setPropertyValue("Name", aAny
);
113 rForm
= uno::Reference
<form::XForm
>(xForm
, uno::UNO_QUERY
);
115 uno::Reference
<container::XIndexContainer
> xForms(xFormsNamedContainer
, uno::UNO_QUERY
);
116 uno::Any
aAny(xForm
);
117 xForms
->insertByIndex(xForms
->getCount(), aAny
);
124 uno::Reference
<container::XIndexContainer
> FormControlHelper::FormControlHelper_Impl::getFormComps()
126 uno::Reference
<container::XIndexContainer
> xIndexContainer(getForm(), uno::UNO_QUERY
);
128 return xIndexContainer
;
131 FormControlHelper::FormControlHelper(FieldId eFieldId
,
132 uno::Reference
<text::XTextDocument
> rTextDocument
,
133 FFDataHandler::Pointer_t pFFData
)
134 : m_pFFData(pFFData
), m_pImpl(new FormControlHelper_Impl
)
136 m_pImpl
->m_eFieldId
= eFieldId
;
137 m_pImpl
->rTextDocument
= rTextDocument
;
140 FormControlHelper::~FormControlHelper()
144 bool FormControlHelper::createCheckbox(uno::Reference
<text::XTextRange
> xTextRange
,
145 const OUString
& rControlName
)
149 uno::Reference
<lang::XMultiServiceFactory
>
150 xServiceFactory(m_pImpl
->getServiceFactory());
152 if (! xServiceFactory
.is())
155 uno::Reference
<uno::XInterface
> xInterface
= xServiceFactory
->createInstance("com.sun.star.form.component.CheckBox");
157 if (!xInterface
.is())
160 m_pImpl
->rFormComponent
= uno::Reference
<form::XFormComponent
>(xInterface
, uno::UNO_QUERY
);
161 if (!m_pImpl
->rFormComponent
.is())
164 uno::Reference
<beans::XPropertySet
> xPropSet(xInterface
, uno::UNO_QUERY
);
166 sal_uInt32 nCheckBoxHeight
= 16 * m_pFFData
->getCheckboxHeight();
168 if (m_pFFData
->getCheckboxAutoHeight())
170 uno::Reference
<beans::XPropertySet
> xTextRangeProps(xTextRange
, uno::UNO_QUERY
);
174 float fCheckBoxHeight
= 0.0;
175 xTextRangeProps
->getPropertyValue("CharHeight") >>= fCheckBoxHeight
;
176 nCheckBoxHeight
= static_cast<sal_uInt32
>(floor(fCheckBoxHeight
* 35.3));
178 catch (beans::UnknownPropertyException
&)
183 m_pImpl
->aSize
.Width
= nCheckBoxHeight
;
184 m_pImpl
->aSize
.Height
= m_pImpl
->aSize
.Width
;
187 if (!m_pFFData
->getStatusText().isEmpty())
189 aAny
<<= m_pFFData
->getStatusText();
191 xPropSet
->setPropertyValue("HelpText", aAny
);
194 aAny
<<= m_pFFData
->getCheckboxChecked();
195 xPropSet
->setPropertyValue("DefaultState", aAny
);
197 if (!m_pFFData
->getHelpText().isEmpty())
199 aAny
<<= m_pFFData
->getHelpText();
200 xPropSet
->setPropertyValue("HelpF1Text", aAny
);
203 aAny
<<= rControlName
;
204 xPropSet
->setPropertyValue("Name", aAny
);
209 bool FormControlHelper::processField(uno::Reference
<text::XFormField
> xFormField
)
212 uno::Reference
<container::XNameContainer
> xNameCont
= xFormField
->getParameters();
213 uno::Reference
<container::XNamed
> xNamed( xFormField
, uno::UNO_QUERY
);
214 if ( m_pFFData
&& xNamed
.is() && xNameCont
.is() )
217 if (m_pImpl
->m_eFieldId
== FIELD_FORMTEXT
)
219 xFormField
->setFieldType(ODF_FORMTEXT
);
220 if ( !m_pFFData
->getName().isEmpty() )
222 xNamed
->setName( m_pFFData
->getName() );
225 else if (m_pImpl
->m_eFieldId
== FIELD_FORMCHECKBOX
)
227 xFormField
->setFieldType(ODF_FORMCHECKBOX
);
228 uno::Reference
<beans::XPropertySet
> xPropSet(xFormField
, uno::UNO_QUERY
);
230 aAny
<<= m_pFFData
->getCheckboxChecked();
232 xPropSet
->setPropertyValue("Checked", aAny
);
234 else if (m_pImpl
->m_eFieldId
== FIELD_FORMDROPDOWN
)
236 xFormField
->setFieldType(ODF_FORMDROPDOWN
);
237 uno::Sequence
< OUString
> sItems
;
238 sItems
.realloc( m_pFFData
->getDropDownEntries().size() );
239 ::std::copy( m_pFFData
->getDropDownEntries().begin(), m_pFFData
->getDropDownEntries().end(), sItems
.begin());
240 if ( sItems
.getLength() )
242 if ( xNameCont
->hasByName(ODF_FORMDROPDOWN_LISTENTRY
) )
243 xNameCont
->replaceByName(ODF_FORMDROPDOWN_LISTENTRY
, uno::makeAny( sItems
) );
245 xNameCont
->insertByName(ODF_FORMDROPDOWN_LISTENTRY
, uno::makeAny( sItems
) );
247 sal_Int32 nResult
= m_pFFData
->getDropDownResult().toInt32();
250 if ( xNameCont
->hasByName(ODF_FORMDROPDOWN_RESULT
) )
251 xNameCont
->replaceByName(ODF_FORMDROPDOWN_RESULT
, uno::makeAny( nResult
) );
253 xNameCont
->insertByName(ODF_FORMDROPDOWN_RESULT
, uno::makeAny( nResult
) );
263 bool FormControlHelper::insertControl(uno::Reference
<text::XTextRange
> xTextRange
)
265 bool bCreated
= false;
268 uno::Reference
<container::XNameContainer
> xFormCompsByName(m_pImpl
->getForm(), uno::UNO_QUERY
);
269 uno::Reference
<container::XIndexContainer
> xFormComps(m_pImpl
->getFormComps());
270 if (! xFormComps
.is())
273 static OUString
sControl("Control");
275 sal_Int32 nControl
= 0;
277 OUString sControlName
;
281 OUString
sTmp(sControl
);
282 sTmp
+= OUString::number(nControl
);
285 if (! xFormCompsByName
->hasByName(sTmp
))
293 switch (m_pImpl
->m_eFieldId
)
295 case FIELD_FORMCHECKBOX
:
296 bCreated
= createCheckbox(xTextRange
, sControlName
);
305 uno::Any
aAny(m_pImpl
->rFormComponent
);
306 xFormComps
->insertByIndex(xFormComps
->getCount(), aAny
);
308 if (! m_pImpl
->getServiceFactory().is())
311 uno::Reference
<uno::XInterface
> xInterface
= m_pImpl
->getServiceFactory()->createInstance("com.sun.star.drawing.ControlShape");
313 if (! xInterface
.is())
316 uno::Reference
<drawing::XShape
> xShape(xInterface
, uno::UNO_QUERY
);
321 xShape
->setSize(m_pImpl
->aSize
);
323 uno::Reference
<beans::XPropertySet
> xShapeProps(xShape
, uno::UNO_QUERY
);
325 sal_uInt16 nTmp
= text::TextContentAnchorType_AS_CHARACTER
;
328 xShapeProps
->setPropertyValue("AnchorType", aAny
);
330 nTmp
= text::VertOrientation::CENTER
;
332 xShapeProps
->setPropertyValue("VertOrient", aAny
);
336 xShapeProps
->setPropertyValue("TextRange", aAny
);
338 uno::Reference
<drawing::XControlShape
> xControlShape(xShape
, uno::UNO_QUERY
);
339 uno::Reference
<awt::XControlModel
> xControlModel(m_pImpl
->rFormComponent
, uno::UNO_QUERY
);
340 xControlShape
->setControl(xControlModel
);
342 m_pImpl
->getDrawPage()->add(xShape
);
349 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */