Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <stdio.h>
31 : : #include "layerexport.hxx"
32 : : #include "strings.hxx"
33 : : #include <xmloff/xmlexp.hxx>
34 : : #include <xmloff/nmspmap.hxx>
35 : : #include "xmloff/xmlnmspe.hxx"
36 : : #include <xmloff/xmluconv.hxx>
37 : : #include <xmloff/xmlprmap.hxx>
38 : : #include <xmloff/prhdlfac.hxx>
39 : : #include "elementexport.hxx"
40 : : #include <xmloff/families.hxx>
41 : : #include <xmloff/contextid.hxx>
42 : : #include <xmloff/controlpropertyhdl.hxx>
43 : : #include <tools/diagnose_ex.h>
44 : : #include "controlpropertymap.hxx"
45 : : #include <com/sun/star/container/XIndexAccess.hpp>
46 : : #include <com/sun/star/form/XFormsSupplier2.hpp>
47 : : #include <com/sun/star/xforms/XFormsSupplier.hpp>
48 : : #include <com/sun/star/form/FormComponentType.hpp>
49 : : #include <com/sun/star/lang/XServiceInfo.hpp>
50 : : #include <com/sun/star/container/XChild.hpp>
51 : : #include <com/sun/star/script/XEventAttacherManager.hpp>
52 : : #include "eventexport.hxx"
53 : : #include <xmloff/XMLEventExport.hxx>
54 : : #include "formevents.hxx"
55 : : #include <xmloff/xmlnumfe.hxx>
56 : : #include "xmloff/xformsexport.hxx"
57 : :
58 : : #include <com/sun/star/text/XText.hpp>
59 : :
60 : : #include <numeric>
61 : :
62 : : //.........................................................................
63 : : namespace xmloff
64 : : {
65 : : //.........................................................................
66 : :
67 : : using namespace ::com::sun::star::uno;
68 : : using namespace ::com::sun::star::awt;
69 : : using namespace ::com::sun::star::lang;
70 : : using namespace ::com::sun::star::beans;
71 : : using namespace ::com::sun::star::container;
72 : : using namespace ::com::sun::star::drawing;
73 : : using namespace ::com::sun::star::form;
74 : : using namespace ::com::sun::star::script;
75 : : using namespace ::com::sun::star::util;
76 : : using namespace ::com::sun::star::text;
77 : :
78 : : typedef ::com::sun::star::xforms::XFormsSupplier XXFormsSupplier;
79 : :
80 : : //=====================================================================
81 : : //= OFormLayerXMLExport_Impl
82 : : //=====================================================================
83 : : //---------------------------------------------------------------------
84 : 0 : const ::rtl::OUString& OFormLayerXMLExport_Impl::getControlNumberStyleNamePrefix()
85 : : {
86 [ # # ][ # # ]: 0 : static const ::rtl::OUString s_sControlNumberStyleNamePrefix("C");
87 : 0 : return s_sControlNumberStyleNamePrefix;
88 : : }
89 : :
90 : : //---------------------------------------------------------------------
91 : 43 : OFormLayerXMLExport_Impl::OFormLayerXMLExport_Impl(SvXMLExport& _rContext)
92 : : :m_rContext(_rContext)
93 [ + - ][ + - ]: 43 : ,m_pControlNumberStyles(NULL)
[ + - ][ + - ]
[ + - ]
94 : : {
95 [ + - ]: 43 : initializePropertyMaps();
96 : :
97 : : // add our style family to the export context's style pool
98 [ + - ][ + - ]: 43 : m_xPropertyHandlerFactory = new OControlPropertyHandlerFactory();
[ + - ]
99 [ + - ][ + - ]: 43 : ::rtl::Reference< XMLPropertySetMapper > xStylePropertiesMapper = new XMLPropertySetMapper( getControlStylePropertyMap(), m_xPropertyHandlerFactory.get() );
[ + - ][ + - ]
[ + - ][ + - ]
100 [ + - ][ + - ]: 43 : m_xStyleExportMapper = new OFormComponentStyleExportMapper( xStylePropertiesMapper.get() );
[ + - ][ + - ]
[ + - ]
101 : :
102 : : // our style family
103 : : m_rContext.GetAutoStylePool()->AddFamily(
104 [ + - ]: 43 : XML_STYLE_FAMILY_CONTROL_ID, token::GetXMLToken(token::XML_PARAGRAPH),
105 : : m_xStyleExportMapper.get(),
106 : : ::rtl::OUString( XML_STYLE_FAMILY_CONTROL_PREFIX )
107 [ + - ][ + - ]: 86 : );
[ + - ][ + - ]
108 : :
109 : : // add our event translation table
110 [ + - ][ + - ]: 43 : m_rContext.GetEventExport().AddTranslationTable(g_pFormsEventTranslation);
111 : :
112 [ + - ]: 43 : clear();
113 : 43 : }
114 : :
115 [ + - ][ + - ]: 43 : OFormLayerXMLExport_Impl::~OFormLayerXMLExport_Impl()
116 : : {
117 [ - + ]: 86 : }
118 : :
119 : : //---------------------------------------------------------------------
120 : 57 : sal_Bool OFormLayerXMLExport_Impl::impl_isFormPageContainingForms(const Reference< XDrawPage >& _rxDrawPage, Reference< XIndexAccess >& _rxForms)
121 : : {
122 [ + - ]: 57 : Reference< XFormsSupplier2 > xFormsSupp(_rxDrawPage, UNO_QUERY);
123 : : OSL_ENSURE(xFormsSupp.is(), "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid draw page (no XFormsSupplier)! Doin' nothing!");
124 [ - + ]: 57 : if (!xFormsSupp.is())
125 : 0 : return sal_False;
126 : :
127 [ + - ][ + - ]: 57 : if ( !xFormsSupp->hasForms() )
[ + - ]
128 : : // nothing to do at all
129 : 57 : return sal_False;
130 : :
131 [ # # ][ # # ]: 0 : _rxForms = Reference< XIndexAccess >(xFormsSupp->getForms(), UNO_QUERY);
[ # # ][ # # ]
132 [ # # ]: 0 : Reference< XServiceInfo > xSI(_rxForms, UNO_QUERY); // order is important!
133 : : OSL_ENSURE(xSI.is(), "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (must not be NULL and must have a ServiceInfo)!");
134 [ # # ]: 0 : if (!xSI.is())
135 : 0 : return sal_False;
136 : :
137 [ # # ][ # # ]: 0 : if (!xSI->supportsService(SERVICE_FORMSCOLLECTION))
[ # # ][ # # ]
138 : : {
139 : : OSL_FAIL("OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (is no com.sun.star.form.Forms)!");
140 : : // nothing to do
141 : 0 : return sal_False;
142 : : }
143 : 57 : return sal_True;
144 : : }
145 : :
146 : : //---------------------------------------------------------------------
147 : 0 : void OFormLayerXMLExport_Impl::exportGridColumn(const Reference< XPropertySet >& _rxColumn,
148 : : const Sequence< ScriptEventDescriptor >& _rEvents)
149 : : {
150 : : // do the exporting
151 [ # # ][ # # ]: 0 : OColumnExport aExportImpl(*this, _rxColumn, getControlId( _rxColumn ), _rEvents);
152 [ # # ][ # # ]: 0 : aExportImpl.doExport();
153 : 0 : }
154 : :
155 : : //---------------------------------------------------------------------
156 : 0 : void OFormLayerXMLExport_Impl::exportControl(const Reference< XPropertySet >& _rxControl,
157 : : const Sequence< ScriptEventDescriptor >& _rEvents)
158 : : {
159 : : // the list of the referring controls
160 : 0 : ::rtl::OUString sReferringControls;
161 [ # # ]: 0 : MapPropertySet2String::const_iterator aReferring = m_aCurrentPageReferring->second.find(_rxControl);
162 [ # # ]: 0 : if (aReferring != m_aCurrentPageReferring->second.end())
163 : 0 : sReferringControls = aReferring->second;
164 : :
165 : : // the control id (should already have been created in examineForms)
166 [ # # ]: 0 : ::rtl::OUString sControlId( getControlId( _rxControl ) );
167 : :
168 : : // do the exporting
169 [ # # ]: 0 : OControlExport aExportImpl(*this, _rxControl, sControlId, sReferringControls, _rEvents);
170 [ # # ][ # # ]: 0 : aExportImpl.doExport();
171 : 0 : }
172 : :
173 : : //---------------------------------------------------------------------
174 : 0 : void OFormLayerXMLExport_Impl::exportForm(const Reference< XPropertySet >& _rxProps,
175 : : const Sequence< ScriptEventDescriptor >& _rEvents)
176 : : {
177 : : OSL_ENSURE(_rxProps.is(), "OFormLayerXMLExport_Impl::exportForm: invalid property set!");
178 [ # # ]: 0 : OFormExport aAttributeHandler(*this, _rxProps, _rEvents);
179 [ # # ][ # # ]: 0 : aAttributeHandler.doExport();
180 : 0 : }
181 : :
182 : : //---------------------------------------------------------------------
183 : 0 : ::rtl::Reference< SvXMLExportPropertyMapper > OFormLayerXMLExport_Impl::getStylePropertyMapper()
184 : : {
185 : 0 : return m_xStyleExportMapper;
186 : : }
187 : :
188 : : //---------------------------------------------------------------------
189 : 0 : SvXMLExport& OFormLayerXMLExport_Impl::getGlobalContext()
190 : : {
191 : 0 : return m_rContext;
192 : : }
193 : :
194 : : //---------------------------------------------------------------------
195 : 0 : void OFormLayerXMLExport_Impl::exportCollectionElements(const Reference< XIndexAccess >& _rxCollection)
196 : : {
197 : : // step through all the elements of the collection
198 [ # # ][ # # ]: 0 : sal_Int32 nElements = _rxCollection->getCount();
199 : :
200 [ # # ]: 0 : Reference< XEventAttacherManager > xElementEventManager(_rxCollection, UNO_QUERY);
201 [ # # ]: 0 : Sequence< ScriptEventDescriptor > aElementEvents;
202 : :
203 : 0 : Reference< XPropertySetInfo > xPropsInfo;
204 : 0 : Reference< XIndexAccess > xCurrentContainer;
205 [ # # ]: 0 : for (sal_Int32 i=0; i<nElements; ++i)
206 : : {
207 : : try
208 : : {
209 : : // extract the current element
210 [ # # ][ # # ]: 0 : Reference< XPropertySet > xCurrentProps( _rxCollection->getByIndex(i), UNO_QUERY );
[ # # ]
211 : : OSL_ENSURE(xCurrentProps.is(), "OFormLayerXMLExport_Impl::exportCollectionElements: invalid child element, skipping!");
212 [ # # ]: 0 : if (!xCurrentProps.is())
213 : 0 : continue;
214 : :
215 : : // check if there is a ClassId property on the current element. If so, we assume it to be a control
216 [ # # ][ # # ]: 0 : xPropsInfo = xCurrentProps->getPropertySetInfo();
[ # # ]
217 : : OSL_ENSURE(xPropsInfo.is(), "OFormLayerXMLExport_Impl::exportCollectionElements: no property set info!");
218 [ # # ]: 0 : if (!xPropsInfo.is())
219 : : // without this, a lot of stuff in the export routines may fail
220 : 0 : continue;
221 : :
222 : : // if the element is part of a ignore list, we are not allowed to export it
223 [ # # ][ # # ]: 0 : if ( m_aIgnoreList.end() != m_aIgnoreList.find( xCurrentProps ) )
224 : 0 : continue;
225 : :
226 [ # # ]: 0 : if (xElementEventManager.is())
227 [ # # ][ # # ]: 0 : aElementEvents = xElementEventManager->getScriptEvents(i);
[ # # ][ # # ]
228 : :
229 [ # # ][ # # ]: 0 : if (xPropsInfo->hasPropertyByName(PROPERTY_COLUMNSERVICENAME))
[ # # ][ # # ]
230 : : {
231 [ # # ]: 0 : exportGridColumn(xCurrentProps, aElementEvents);
232 : : }
233 [ # # ][ # # ]: 0 : else if (xPropsInfo->hasPropertyByName(PROPERTY_CLASSID))
[ # # ][ # # ]
234 : : {
235 [ # # ]: 0 : exportControl(xCurrentProps, aElementEvents);
236 : : }
237 : : else
238 : : {
239 [ # # ]: 0 : exportForm(xCurrentProps, aElementEvents);
240 [ # # ][ # # ]: 0 : }
241 : : }
242 [ # # ]: 0 : catch(Exception&)
243 : : {
244 : : OSL_FAIL("OFormLayerXMLExport_Impl::exportCollectionElements: caught an exception ... skipping the current element!");
245 : 0 : continue;
246 : : }
247 [ # # ]: 0 : }
248 : 0 : }
249 : :
250 : : //---------------------------------------------------------------------
251 : 0 : ::rtl::OUString OFormLayerXMLExport_Impl::getObjectStyleName( const Reference< XPropertySet >& _rxObject )
252 : : {
253 : 0 : ::rtl::OUString aObjectStyle;
254 : :
255 [ # # ]: 0 : MapPropertySet2String::const_iterator aObjectStylePos = m_aGridColumnStyles.find( _rxObject );
256 [ # # ]: 0 : if ( m_aGridColumnStyles.end() != aObjectStylePos )
257 : 0 : aObjectStyle = aObjectStylePos->second;
258 : 0 : return aObjectStyle;
259 : : }
260 : :
261 : : //---------------------------------------------------------------------
262 : 43 : void OFormLayerXMLExport_Impl::clear()
263 : : {
264 : 43 : m_aControlIds.clear();
265 : 43 : m_aReferringControls.clear();
266 : 43 : m_aCurrentPageIds = m_aControlIds.end();
267 : 43 : m_aCurrentPageReferring = m_aReferringControls.end();
268 : :
269 : 43 : m_aControlNumberFormats.clear();
270 : 43 : m_aGridColumnStyles.clear();
271 : :
272 : 43 : m_aIgnoreList.clear();
273 : 43 : }
274 : :
275 : : //---------------------------------------------------------------------
276 : 41 : void OFormLayerXMLExport_Impl::exportAutoControlNumberStyles()
277 : : {
278 [ - + ]: 41 : if ( m_pControlNumberStyles )
279 : 0 : m_pControlNumberStyles->Export( sal_True );
280 : 41 : }
281 : :
282 : : //---------------------------------------------------------------------
283 : 37 : void OFormLayerXMLExport_Impl::exportAutoStyles()
284 : : {
285 : : m_rContext.GetAutoStylePool()->exportXML(
286 : : XML_STYLE_FAMILY_CONTROL_ID,
287 : 37 : m_rContext.GetDocHandler(),
288 : 37 : m_rContext.GetMM100UnitConverter(),
289 : 37 : m_rContext.GetNamespaceMap()
290 [ + - ][ + - ]: 37 : );
291 : 37 : }
292 : :
293 : : //---------------------------------------------------------------------
294 : 0 : void OFormLayerXMLExport_Impl::exportForms(const Reference< XDrawPage >& _rxDrawPage)
295 : : {
296 : : // get the forms collection of the page
297 : 0 : Reference< XIndexAccess > xCollectionIndex;
298 [ # # ][ # # ]: 0 : if (!impl_isFormPageContainingForms(_rxDrawPage, xCollectionIndex))
299 : 0 : return;
300 : :
301 : : #if OSL_DEBUG_LEVEL > 0
302 : : sal_Bool bPageIsKnown =
303 : : #endif
304 [ # # ]: 0 : implMoveIterators(_rxDrawPage, sal_False);
305 : : OSL_ENSURE(bPageIsKnown, "OFormLayerXMLExport_Impl::exportForms: exporting a page which has not been examined!");
306 : :
307 : : // export forms collection
308 [ # # ][ # # ]: 0 : exportCollectionElements(xCollectionIndex);
309 : : }
310 : :
311 : : //---------------------------------------------------------------------
312 : 0 : void OFormLayerXMLExport_Impl::exportXForms() const
313 : : {
314 : : // export XForms models
315 : 0 : ::exportXForms( m_rContext );
316 : 0 : }
317 : :
318 : : //---------------------------------------------------------------------
319 : 21 : bool OFormLayerXMLExport_Impl::pageContainsForms( const Reference< XDrawPage >& _rxDrawPage ) const
320 : : {
321 [ + - ]: 21 : Reference< XFormsSupplier2 > xFormsSupp( _rxDrawPage, UNO_QUERY );
322 : : DBG_ASSERT( xFormsSupp.is(), "OFormLayerXMLExport_Impl::pageContainsForms: no XFormsSupplier2!" );
323 [ + - ][ + - ]: 21 : return xFormsSupp.is() && xFormsSupp->hasForms();
[ + - ][ - + ]
324 : : }
325 : :
326 : : //---------------------------------------------------------------------
327 : 21 : bool OFormLayerXMLExport_Impl::documentContainsXForms() const
328 : : {
329 [ + - ]: 21 : Reference< XXFormsSupplier > xXFormSupp( m_rContext.GetModel(), UNO_QUERY );
330 : 21 : Reference< XNameContainer > xForms;
331 [ + - ]: 21 : if ( xXFormSupp.is() )
332 [ + - ][ + - ]: 21 : xForms = xXFormSupp->getXForms();
[ + - ]
333 [ - + ][ # # ]: 21 : return xForms.is() && xForms->hasElements();
[ # # ][ # # ]
334 : : }
335 : :
336 : : //---------------------------------------------------------------------
337 : 36 : sal_Bool OFormLayerXMLExport_Impl::implMoveIterators(const Reference< XDrawPage >& _rxDrawPage, sal_Bool _bClear)
338 : : {
339 [ - + ]: 36 : if (!_rxDrawPage.is())
340 : 0 : return false;
341 : :
342 : 36 : sal_Bool bKnownPage = sal_False;
343 : :
344 : : // the one for the ids
345 : 36 : m_aCurrentPageIds = m_aControlIds.find(_rxDrawPage);
346 [ + + ]: 36 : if (m_aControlIds.end() == m_aCurrentPageIds)
347 : : {
348 [ + - ][ + - ]: 30 : m_aControlIds[_rxDrawPage] = MapPropertySet2String();
349 : 30 : m_aCurrentPageIds = m_aControlIds.find(_rxDrawPage);
350 : : }
351 : : else
352 : : {
353 : 6 : bKnownPage = sal_True;
354 [ - + ][ # # ]: 6 : if (_bClear && !m_aCurrentPageIds->second.empty() )
[ - + ]
355 : 0 : m_aCurrentPageIds->second.clear();
356 : : }
357 : :
358 : : // the one for the ids of the referring controls
359 : 36 : m_aCurrentPageReferring = m_aReferringControls.find(_rxDrawPage);
360 [ + + ]: 36 : if (m_aReferringControls.end() == m_aCurrentPageReferring)
361 : : {
362 [ + - ][ + - ]: 30 : m_aReferringControls[_rxDrawPage] = MapPropertySet2String();
363 : 30 : m_aCurrentPageReferring = m_aReferringControls.find(_rxDrawPage);
364 : : }
365 : : else
366 : : {
367 : 6 : bKnownPage = sal_True;
368 [ - + ][ # # ]: 6 : if (_bClear && !m_aCurrentPageReferring->second.empty() )
[ - + ]
369 : 0 : m_aCurrentPageReferring->second.clear();
370 : : }
371 : 36 : return bKnownPage;
372 : : }
373 : :
374 : : //---------------------------------------------------------------------
375 : 36 : sal_Bool OFormLayerXMLExport_Impl::seekPage(const Reference< XDrawPage >& _rxDrawPage)
376 : : {
377 [ + - ]: 36 : sal_Bool bKnownPage = implMoveIterators( _rxDrawPage, sal_False );
378 [ + + ]: 36 : if ( bKnownPage )
379 : 6 : return sal_True;
380 : :
381 : : // if the page is not yet known, this does not automatically mean that it has
382 : : // not been examined. Instead, examineForms returns silently and successfully
383 : : // if a page is a XFormsPageSupplier2, but does not have a forms collection
384 : : // (This behaviour of examineForms is a performance optimization, to not force
385 : : // the page to create a forms container just to see that it's empty.)
386 : :
387 : : // So, in such a case, seekPage is considered to be successfull, too, though the
388 : : // page was not yet known
389 [ + - ]: 30 : Reference< XFormsSupplier2 > xFormsSupp( _rxDrawPage, UNO_QUERY );
390 [ + - ][ + - ]: 30 : if ( xFormsSupp.is() && !xFormsSupp->hasForms() )
[ + - ][ + - ]
[ + - ]
391 : 30 : return sal_True;
392 : :
393 : : // anything else means that the page has not been examined before, or it's no
394 : : // valid form page. Both cases are Bad (TM).
395 : 36 : return sal_False;
396 : : }
397 : :
398 : : //---------------------------------------------------------------------
399 : 0 : ::rtl::OUString OFormLayerXMLExport_Impl::getControlId(const Reference< XPropertySet >& _rxControl)
400 : : {
401 [ # # ]: 0 : if (m_aCurrentPageIds == m_aControlIds.end())
402 : 0 : return ::rtl::OUString();
403 : :
404 : : OSL_ENSURE(m_aCurrentPageIds->second.end() != m_aCurrentPageIds->second.find(_rxControl),
405 : : "OFormLayerXMLExport_Impl::getControlId: can not find the control!");
406 : 0 : return m_aCurrentPageIds->second[_rxControl];
407 : : }
408 : :
409 : : //---------------------------------------------------------------------
410 : 0 : ::rtl::OUString OFormLayerXMLExport_Impl::getImmediateNumberStyle( const Reference< XPropertySet >& _rxObject )
411 : : {
412 : 0 : ::rtl::OUString sNumberStyle;
413 : :
414 [ # # ]: 0 : sal_Int32 nOwnFormatKey = implExamineControlNumberFormat( _rxObject );
415 [ # # ]: 0 : if ( -1 != nOwnFormatKey )
416 [ # # ][ # # ]: 0 : sNumberStyle = getControlNumberStyleExport()->GetStyleName( nOwnFormatKey );
417 : :
418 : 0 : return sNumberStyle;
419 : : }
420 : :
421 : : //---------------------------------------------------------------------
422 : 0 : ::rtl::OUString OFormLayerXMLExport_Impl::getControlNumberStyle( const Reference< XPropertySet >& _rxControl )
423 : : {
424 : 0 : ::rtl::OUString sNumberStyle;
425 : :
426 [ # # ]: 0 : ConstMapPropertySet2IntIterator aControlFormatPos = m_aControlNumberFormats.find(_rxControl);
427 [ # # ]: 0 : if (m_aControlNumberFormats.end() != aControlFormatPos)
428 : : {
429 : : OSL_ENSURE(m_pControlNumberStyles, "OFormLayerXMLExport_Impl::getControlNumberStyle: have a control which has a format style, but no style exporter!");
430 [ # # ][ # # ]: 0 : sNumberStyle = getControlNumberStyleExport()->GetStyleName(aControlFormatPos->second);
431 : : }
432 : : // it's allowed to ask for a control which does not have format information.
433 : : // (This is for performance reasons)
434 : :
435 : 0 : return sNumberStyle;
436 : : }
437 : :
438 : : //---------------------------------------------------------------------
439 : 57 : void OFormLayerXMLExport_Impl::examineForms(const Reference< XDrawPage >& _rxDrawPage)
440 : : {
441 : : // get the forms collection of the page
442 : 57 : Reference< XIndexAccess > xCollectionIndex;
443 [ + - ][ + - ]: 57 : if (!impl_isFormPageContainingForms(_rxDrawPage, xCollectionIndex))
444 : 57 : return;
445 : :
446 : : // move the iterator which specify the currently handled page
447 : : #if OSL_DEBUG_LEVEL > 0
448 : : sal_Bool bPageIsKnown =
449 : : #endif
450 [ # # ]: 0 : implMoveIterators(_rxDrawPage, sal_True);
451 : : OSL_ENSURE(!bPageIsKnown, "OFormLayerXMLExport_Impl::examineForms: examining a page twice!");
452 : :
453 [ # # ][ # # ]: 0 : ::std::stack< Reference< XIndexAccess > > aContainerHistory;
454 [ # # ][ # # ]: 0 : ::std::stack< sal_Int32 > aIndexHistory;
455 : :
456 : 0 : Reference< XIndexAccess > xLoop = xCollectionIndex;
457 : 0 : sal_Int32 nChildPos = 0;
458 [ # # ]: 0 : do
459 : : {
460 [ # # ][ # # ]: 0 : if (nChildPos < xLoop->getCount())
[ # # ]
461 : : {
462 [ # # ][ # # ]: 0 : Reference< XPropertySet > xCurrent( xLoop->getByIndex( nChildPos ), UNO_QUERY );
[ # # ]
463 : : OSL_ENSURE(xCurrent.is(), "OFormLayerXMLExport_Impl::examineForms: invalid child object");
464 [ # # ]: 0 : if (!xCurrent.is())
465 : 0 : continue;
466 : :
467 [ # # ][ # # ]: 0 : if (!checkExamineControl(xCurrent))
468 : : {
469 : : // step down
470 [ # # ]: 0 : Reference< XIndexAccess > xNextContainer(xCurrent, UNO_QUERY);
471 : : OSL_ENSURE(xNextContainer.is(), "OFormLayerXMLExport_Impl::examineForms: what the heck is this ... no control, no container?");
472 [ # # ]: 0 : aContainerHistory.push(xLoop);
473 [ # # ]: 0 : aIndexHistory.push(nChildPos);
474 : :
475 [ # # ]: 0 : xLoop = xNextContainer;
476 : 0 : nChildPos = -1; // will be incremented below
477 : : }
478 [ # # ]: 0 : ++nChildPos;
479 : : }
480 : : else
481 : : {
482 : : // step up
483 [ # # ][ # # ]: 0 : while ((nChildPos >= xLoop->getCount()) && !aContainerHistory.empty() )
[ # # ][ # # ]
[ # # ]
484 : : {
485 [ # # ][ # # ]: 0 : xLoop = aContainerHistory.top();
486 [ # # ]: 0 : aContainerHistory.pop();
487 [ # # ]: 0 : nChildPos = aIndexHistory.top();
488 [ # # ]: 0 : aIndexHistory.pop();
489 : :
490 : 0 : ++nChildPos;
491 : : }
492 [ # # ][ # # ]: 0 : if (nChildPos >= xLoop->getCount())
[ # # ]
493 : : // exited the loop above because we have no history anymore (0 == aContainerHistory.size()),
494 : : // and on the current level there are no more children
495 : : // -> leave
496 : 0 : break;
497 : : }
498 : : }
499 [ - + ]: 57 : while (xLoop.is());
500 : : }
501 : :
502 : : //---------------------------------------------------------------------
503 : : namespace
504 : : {
505 : : struct AccumulateSize : public ::std::binary_function< size_t, MapPropertySet2Map::value_type, size_t >
506 : : {
507 : 0 : size_t operator()( size_t _size, const MapPropertySet2Map::value_type& _map ) const
508 : : {
509 : 0 : return _size + _map.second.size();
510 : : }
511 : : };
512 : :
513 : 0 : ::rtl::OUString lcl_findFreeControlId( const MapPropertySet2Map& _rAllPagesControlIds )
514 : : {
515 [ # # ][ # # ]: 0 : static const ::rtl::OUString sControlIdBase( "control" );
516 : 0 : ::rtl::OUString sControlId = sControlIdBase;
517 : :
518 [ # # ]: 0 : size_t nKnownControlCount = ::std::accumulate( _rAllPagesControlIds.begin(), _rAllPagesControlIds.end(), (size_t)0, AccumulateSize() );
519 : 0 : sControlId += ::rtl::OUString::valueOf( (sal_Int32)nKnownControlCount + 1 );
520 : :
521 : : #ifdef DBG_UTIL
522 : : // Check if the id is already used. It shouldn't, as we currently have no mechanism for removing entries
523 : : // from the map, so the approach used above (take the accumulated map size) should be sufficient. But if
524 : : // somebody changes this (e.g. allows removing entries from the map), the assertion below probably will fail.
525 : : for ( MapPropertySet2Map::const_iterator outer = _rAllPagesControlIds.begin();
526 : : outer != _rAllPagesControlIds.end();
527 : : ++outer
528 : : )
529 : : for ( MapPropertySet2String::const_iterator inner = outer->second.begin();
530 : : inner != outer->second.end();
531 : : ++inner
532 : : )
533 : : {
534 : : OSL_ENSURE( inner->second != sControlId,
535 : : "lcl_findFreeControlId: auto-generated control ID is already used!" );
536 : : }
537 : : #endif
538 : 0 : return sControlId;
539 : : }
540 : : }
541 : :
542 : : //---------------------------------------------------------------------
543 : 0 : sal_Bool OFormLayerXMLExport_Impl::checkExamineControl(const Reference< XPropertySet >& _rxObject)
544 : : {
545 [ # # ][ # # ]: 0 : Reference< XPropertySetInfo > xCurrentInfo = _rxObject->getPropertySetInfo();
546 : : OSL_ENSURE(xCurrentInfo.is(), "OFormLayerXMLExport_Impl::checkExamineControl: no property set info");
547 : :
548 [ # # ][ # # ]: 0 : sal_Bool bIsControl = xCurrentInfo->hasPropertyByName( PROPERTY_CLASSID );
[ # # ]
549 [ # # ]: 0 : if (bIsControl)
550 : : {
551 : : // ----------------------------------
552 : : // generate a new control id
553 : :
554 : : // find a free id
555 [ # # ]: 0 : ::rtl::OUString sCurrentId = lcl_findFreeControlId( m_aControlIds );
556 : : // add it to the map
557 [ # # ]: 0 : m_aCurrentPageIds->second[_rxObject] = sCurrentId;
558 : :
559 : : // ----------------------------------
560 : : // check if this control has a "LabelControl" property referring another control
561 [ # # ][ # # ]: 0 : if ( xCurrentInfo->hasPropertyByName( PROPERTY_CONTROLLABEL ) )
[ # # ][ # # ]
562 : : {
563 [ # # ][ # # ]: 0 : Reference< XPropertySet > xCurrentReference( _rxObject->getPropertyValue( PROPERTY_CONTROLLABEL ), UNO_QUERY );
[ # # ][ # # ]
564 [ # # ]: 0 : if (xCurrentReference.is())
565 : : {
566 [ # # ]: 0 : ::rtl::OUString& sReferencedBy = m_aCurrentPageReferring->second[xCurrentReference];
567 [ # # ]: 0 : if (!sReferencedBy.isEmpty())
568 : : // it's not the first _rxObject referring to the xCurrentReference
569 : : // -> separate the id
570 : 0 : sReferencedBy += ::rtl::OUString(",");
571 : 0 : sReferencedBy += sCurrentId;
572 : 0 : }
573 : : }
574 : :
575 : : // ----------------------------------
576 : : // check if the control needs a number format style
577 [ # # ][ # # ]: 0 : if ( xCurrentInfo->hasPropertyByName( PROPERTY_FORMATKEY ) )
[ # # ][ # # ]
578 : : {
579 [ # # ]: 0 : examineControlNumberFormat(_rxObject);
580 : : }
581 : :
582 : : // ----------------------------------
583 : : // check if it's a control providing text
584 [ # # ]: 0 : Reference< XText > xControlText( _rxObject, UNO_QUERY );
585 [ # # ]: 0 : if ( xControlText.is() )
586 : : {
587 [ # # ][ # # ]: 0 : m_rContext.GetTextParagraphExport()->collectTextAutoStyles( xControlText );
[ # # ][ # # ]
588 : : }
589 : :
590 : : // ----------------------------------
591 : : // check if it is a grid control - in this case, we need special handling for the columns
592 : 0 : sal_Int16 nControlType = FormComponentType::CONTROL;
593 [ # # ][ # # ]: 0 : _rxObject->getPropertyValue( PROPERTY_CLASSID ) >>= nControlType;
[ # # ]
594 [ # # ]: 0 : if ( FormComponentType::GRIDCONTROL == nControlType )
595 : : {
596 [ # # ]: 0 : collectGridColumnStylesAndIds( _rxObject );
597 : 0 : }
598 : : }
599 : :
600 : 0 : return bIsControl;
601 : : }
602 : :
603 : : //---------------------------------------------------------------------
604 : 0 : void OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds( const Reference< XPropertySet >& _rxControl )
605 : : {
606 : : // loop through all columns of the grid
607 : : try
608 : : {
609 [ # # ]: 0 : Reference< XIndexAccess > xContainer( _rxControl, UNO_QUERY );
610 : : OSL_ENSURE( xContainer.is(), "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: grid control not being a container?!" );
611 [ # # ]: 0 : if ( !xContainer.is() )
612 : 0 : return;
613 : :
614 : 0 : Reference< XPropertySetInfo > xColumnPropertiesMeta;
615 : :
616 [ # # ][ # # ]: 0 : sal_Int32 nCount = xContainer->getCount();
617 [ # # ]: 0 : for ( sal_Int32 i=0; i<nCount; ++i )
618 : : {
619 [ # # ][ # # ]: 0 : Reference< XPropertySet > xColumnProperties( xContainer->getByIndex( i ), UNO_QUERY );
[ # # ]
620 : : OSL_ENSURE( xColumnProperties.is(), "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: invalid grid column encountered!" );
621 [ # # ]: 0 : if ( !xColumnProperties.is() )
622 : 0 : continue;
623 : :
624 : : // ----------------------------------
625 : : // generate a new control id
626 : :
627 : : // find a free id
628 [ # # ]: 0 : ::rtl::OUString sCurrentId = lcl_findFreeControlId( m_aControlIds );
629 : : // add it to the map
630 [ # # ]: 0 : m_aCurrentPageIds->second[ xColumnProperties ] = sCurrentId;
631 : :
632 : : // ----------------------------------
633 : : // determine a number style, if needed
634 [ # # ][ # # ]: 0 : xColumnPropertiesMeta = xColumnProperties->getPropertySetInfo();
[ # # ]
635 : : // get the styles of the column
636 [ # # ]: 0 : ::std::vector< XMLPropertyState > aPropertyStates = m_xStyleExportMapper->Filter( xColumnProperties );
637 : :
638 : : // care for the number format, additionally
639 : 0 : ::rtl::OUString sColumnNumberStyle;
640 [ # # ][ # # ]: 0 : if ( xColumnPropertiesMeta.is() && xColumnPropertiesMeta->hasPropertyByName( PROPERTY_FORMATKEY ) )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
[ # # ]
641 [ # # ]: 0 : sColumnNumberStyle = getImmediateNumberStyle( xColumnProperties );
642 : :
643 [ # # ]: 0 : if ( !sColumnNumberStyle.isEmpty() )
644 : : { // the column indeed has a formatting
645 [ # # ][ # # ]: 0 : sal_Int32 nStyleMapIndex = m_xStyleExportMapper->getPropertySetMapper()->FindEntryIndex( CTF_FORMS_DATA_STYLE );
646 : : // TODO: move this to the ctor
647 : : OSL_ENSURE ( -1 != nStyleMapIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for our context id!");
648 : :
649 [ # # ]: 0 : XMLPropertyState aNumberStyleState( nStyleMapIndex, makeAny( sColumnNumberStyle ) );
650 [ # # ]: 0 : aPropertyStates.push_back( aNumberStyleState );
651 : : }
652 : :
653 : : #if OSL_DEBUG_LEVEL > 0
654 : : ::std::vector< XMLPropertyState >::const_iterator aHaveALook = aPropertyStates.begin();
655 : : for ( ; aHaveALook != aPropertyStates.end(); ++aHaveALook )
656 : : {
657 : : (void)aHaveALook;
658 : : }
659 : : #endif
660 : :
661 : : // ----------------------------------
662 : : // determine the column style
663 : :
664 [ # # ]: 0 : if ( !aPropertyStates.empty() )
665 : : { // add to the style pool
666 [ # # ][ # # ]: 0 : ::rtl::OUString sColumnStyleName = m_rContext.GetAutoStylePool()->Add( XML_STYLE_FAMILY_CONTROL_ID, aPropertyStates );
[ # # ][ # # ]
667 : :
668 : : OSL_ENSURE( m_aGridColumnStyles.end() == m_aGridColumnStyles.find( xColumnProperties ),
669 : : "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: already have a style for this column!" );
670 : :
671 [ # # ][ # # ]: 0 : m_aGridColumnStyles.insert( MapPropertySet2String::value_type( xColumnProperties, sColumnStyleName ) );
[ # # ]
672 : : }
673 [ # # ][ # # ]: 0 : }
[ # # ]
674 : : }
675 : 0 : catch( const Exception& )
676 : : {
677 : : DBG_UNHANDLED_EXCEPTION();
678 : : }
679 : : }
680 : :
681 : : //---------------------------------------------------------------------
682 : 0 : sal_Int32 OFormLayerXMLExport_Impl::implExamineControlNumberFormat( const Reference< XPropertySet >& _rxObject )
683 : : {
684 : : // get the format key relative to our own formats supplier
685 : 0 : sal_Int32 nOwnFormatKey = ensureTranslateFormat( _rxObject );
686 : :
687 [ # # ]: 0 : if ( -1 != nOwnFormatKey )
688 : : // tell the exporter that we used this format
689 : 0 : getControlNumberStyleExport()->SetUsed( nOwnFormatKey );
690 : :
691 : 0 : return nOwnFormatKey;
692 : : }
693 : :
694 : : //---------------------------------------------------------------------
695 : 0 : void OFormLayerXMLExport_Impl::examineControlNumberFormat( const Reference< XPropertySet >& _rxControl )
696 : : {
697 : 0 : sal_Int32 nOwnFormatKey = implExamineControlNumberFormat( _rxControl );
698 : :
699 [ # # ]: 0 : if ( -1 == nOwnFormatKey )
700 : : // nothing to do, the number format of this control is void
701 : 0 : return;
702 : :
703 : : // remember the format key for this control (we'll be asked in getControlNumberStyle for this)
704 : : OSL_ENSURE(m_aControlNumberFormats.end() == m_aControlNumberFormats.find(_rxControl),
705 : : "OFormLayerXMLExport_Impl::examineControlNumberFormat: already handled this control!");
706 : 0 : m_aControlNumberFormats[_rxControl] = nOwnFormatKey;
707 : : }
708 : :
709 : : //---------------------------------------------------------------------
710 : 0 : sal_Int32 OFormLayerXMLExport_Impl::ensureTranslateFormat(const Reference< XPropertySet >& _rxFormattedControl)
711 : : {
712 [ # # ]: 0 : ensureControlNumberStyleExport();
713 : : OSL_ENSURE(m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: no own formats supplier!");
714 : : // (should have been created in ensureControlNumberStyleExport)
715 : :
716 : 0 : sal_Int32 nOwnFormatKey = -1;
717 : :
718 : : // the format key (relative to the control's supplier)
719 : 0 : sal_Int32 nControlFormatKey = -1;
720 [ # # ][ # # ]: 0 : Any aControlFormatKey = _rxFormattedControl->getPropertyValue(PROPERTY_FORMATKEY);
[ # # ]
721 [ # # ]: 0 : if (aControlFormatKey >>= nControlFormatKey)
722 : : {
723 : : // the control's number format
724 : 0 : Reference< XNumberFormatsSupplier > xControlFormatsSupplier;
725 [ # # ][ # # ]: 0 : _rxFormattedControl->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xControlFormatsSupplier;
[ # # ][ # # ]
726 : 0 : Reference< XNumberFormats > xControlFormats;
727 [ # # ]: 0 : if (xControlFormatsSupplier.is())
728 [ # # ][ # # ]: 0 : xControlFormats = xControlFormatsSupplier->getNumberFormats();
[ # # ]
729 : : OSL_ENSURE(xControlFormats.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: formatted control without supplier!");
730 : :
731 : : // obtain the persistent (does not depend on the formats supplier) representation of the control's format
732 : 0 : Locale aFormatLocale;
733 : 0 : ::rtl::OUString sFormatDescription;
734 [ # # ]: 0 : if (xControlFormats.is())
735 : : {
736 [ # # ][ # # ]: 0 : Reference< XPropertySet > xControlFormat = xControlFormats->getByKey(nControlFormatKey);
737 : :
738 [ # # ][ # # ]: 0 : xControlFormat->getPropertyValue(PROPERTY_LOCALE) >>= aFormatLocale;
[ # # ][ # # ]
739 [ # # ][ # # ]: 0 : xControlFormat->getPropertyValue(PROPERTY_FORMATSTRING) >>= sFormatDescription;
[ # # ]
740 : : }
741 : :
742 : : // check if our own formats collection already knows the format
743 [ # # ][ # # ]: 0 : nOwnFormatKey = m_xControlNumberFormats->queryKey(sFormatDescription, aFormatLocale, sal_False);
744 [ # # ]: 0 : if (-1 == nOwnFormatKey)
745 : : { // no, we don't
746 : : // -> create a new format
747 [ # # ][ # # ]: 0 : nOwnFormatKey = m_xControlNumberFormats->addNew(sFormatDescription, aFormatLocale);
748 : : }
749 : 0 : OSL_ENSURE(-1 != nOwnFormatKey, "OFormLayerXMLExport_Impl::ensureTranslateFormat: could not translate the controls format key!");
750 : : }
751 : : else
752 : : OSL_ENSURE(!aControlFormatKey.hasValue(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: invalid number format property value!");
753 : :
754 : 0 : return nOwnFormatKey;
755 : : }
756 : :
757 : : //---------------------------------------------------------------------
758 : 0 : void OFormLayerXMLExport_Impl::ensureControlNumberStyleExport()
759 : : {
760 [ # # ]: 0 : if (!m_pControlNumberStyles)
761 : : {
762 : : // create our number formats supplier (if necessary)
763 : 0 : Reference< XNumberFormatsSupplier > xFormatsSupplier;
764 : :
765 : : OSL_ENSURE(!m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: inconsistence!");
766 : : // the m_xControlNumberFormats and m_pControlNumberStyles should be maintained together
767 : :
768 : : try
769 : : {
770 : : // create it for en-US (does not really matter, as we will specify a locale for every
771 : : // concrete language to use)
772 [ # # ]: 0 : Sequence< Any > aSupplierArgs(1);
773 [ # # ]: 0 : aSupplierArgs[0] <<= Locale ( ::rtl::OUString("en"),
774 : : ::rtl::OUString("US"),
775 : : ::rtl::OUString()
776 [ # # ]: 0 : );
777 : :
778 : : Reference< XInterface > xFormatsSupplierUntyped =
779 [ # # ][ # # ]: 0 : m_rContext.getServiceFactory()->createInstanceWithArguments(
780 : : SERVICE_NUMBERFORMATSSUPPLIER,
781 : : aSupplierArgs
782 [ # # ][ # # ]: 0 : );
783 : : OSL_ENSURE(xFormatsSupplierUntyped.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: could not instantiate a number formats supplier!");
784 : :
785 [ # # ][ # # ]: 0 : xFormatsSupplier = Reference< XNumberFormatsSupplier >(xFormatsSupplierUntyped, UNO_QUERY);
786 [ # # ]: 0 : if (xFormatsSupplier.is())
787 [ # # ][ # # ]: 0 : m_xControlNumberFormats = xFormatsSupplier->getNumberFormats();
[ # # ][ # # ]
[ # # ]
788 : : }
789 [ # # ]: 0 : catch(const Exception&)
790 : : {
791 : : }
792 : :
793 : : OSL_ENSURE(m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: could not obtain my default number formats!");
794 : :
795 : : // create the exporter
796 [ # # ][ # # ]: 0 : m_pControlNumberStyles = new SvXMLNumFmtExport(m_rContext, xFormatsSupplier, getControlNumberStyleNamePrefix());
[ # # ]
797 : : }
798 : 0 : }
799 : :
800 : : //---------------------------------------------------------------------
801 : 0 : SvXMLNumFmtExport* OFormLayerXMLExport_Impl::getControlNumberStyleExport()
802 : : {
803 : 0 : ensureControlNumberStyleExport();
804 : 0 : return m_pControlNumberStyles;
805 : : }
806 : :
807 : : //---------------------------------------------------------------------
808 : 0 : void OFormLayerXMLExport_Impl::excludeFromExport( const Reference< XControlModel > _rxControl )
809 : : {
810 [ # # ]: 0 : Reference< XPropertySet > xProps( _rxControl, UNO_QUERY );
811 : : OSL_ENSURE( xProps.is(), "OFormLayerXMLExport_Impl::excludeFromExport: invalid control model!" );
812 : : #if OSL_DEBUG_LEVEL > 0
813 : : ::std::pair< PropertySetBag::iterator, bool > aPos =
814 : : #endif
815 [ # # ]: 0 : m_aIgnoreList.insert( xProps );
816 : 0 : OSL_ENSURE( aPos.second, "OFormLayerXMLExport_Impl::excludeFromExport: element already exists in the ignore list!" );
817 : 0 : }
818 : :
819 : : //.........................................................................
820 : : } // namespace xmloff
821 : : //.........................................................................
822 : :
823 : :
824 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|