Update ooo320-m1
[ooovba.git] / xmloff / source / forms / layerexport.cxx
blobeb8c56b610e35e390ea82181d0ed8d9f5145d830
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: layerexport.cxx,v $
10 * $Revision: 1.36.102.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
34 #include <stdio.h>
35 #include "layerexport.hxx"
36 #include "strings.hxx"
37 #include <xmloff/xmlexp.hxx>
38 #include <xmloff/nmspmap.hxx>
39 #include "xmlnmspe.hxx"
40 #include <xmloff/xmluconv.hxx>
41 #include <xmloff/xmlprmap.hxx>
42 #include <xmloff/prhdlfac.hxx>
43 #include "elementexport.hxx"
44 #include <xmloff/families.hxx>
45 #include <xmloff/contextid.hxx>
46 #include <xmloff/controlpropertyhdl.hxx>
47 #include <tools/diagnose_ex.h>
48 #include "controlpropertymap.hxx"
49 #include <com/sun/star/container/XIndexAccess.hpp>
50 #include <com/sun/star/form/XFormsSupplier2.hpp>
51 #include <com/sun/star/xforms/XFormsSupplier.hpp>
52 #include <com/sun/star/form/FormComponentType.hpp>
53 #include <com/sun/star/lang/XServiceInfo.hpp>
54 #include <com/sun/star/container/XChild.hpp>
55 #include <com/sun/star/script/XEventAttacherManager.hpp>
56 #include "eventexport.hxx"
57 #include <xmloff/XMLEventExport.hxx>
58 #include "formevents.hxx"
59 #include <xmloff/xmlnumfe.hxx>
60 #include "xformsexport.hxx"
62 /** === begin UNO includes === **/
63 #include <com/sun/star/text/XText.hpp>
64 /** === end UNO includes === **/
66 #include <numeric>
68 //.........................................................................
69 namespace xmloff
71 //.........................................................................
73 using namespace ::com::sun::star::uno;
74 using namespace ::com::sun::star::awt;
75 using namespace ::com::sun::star::lang;
76 using namespace ::com::sun::star::beans;
77 using namespace ::com::sun::star::container;
78 using namespace ::com::sun::star::drawing;
79 using namespace ::com::sun::star::form;
80 using namespace ::com::sun::star::script;
81 using namespace ::com::sun::star::util;
82 using namespace ::com::sun::star::text;
84 typedef ::com::sun::star::xforms::XFormsSupplier XXFormsSupplier;
86 //=====================================================================
87 //= OFormLayerXMLExport_Impl
88 //=====================================================================
89 //---------------------------------------------------------------------
90 const ::rtl::OUString& OFormLayerXMLExport_Impl::getControlNumberStyleNamePrefix()
92 static const ::rtl::OUString s_sControlNumberStyleNamePrefix = ::rtl::OUString::createFromAscii("C");
93 return s_sControlNumberStyleNamePrefix;
96 //---------------------------------------------------------------------
97 OFormLayerXMLExport_Impl::OFormLayerXMLExport_Impl(SvXMLExport& _rContext)
98 :m_rContext(_rContext)
99 ,m_pControlNumberStyles(NULL)
101 initializePropertyMaps();
103 // add our style family to the export context's style pool
104 m_xPropertyHandlerFactory = new OControlPropertyHandlerFactory();
105 ::vos::ORef< XMLPropertySetMapper > xStylePropertiesMapper = new XMLPropertySetMapper( getControlStylePropertyMap(), m_xPropertyHandlerFactory.getBodyPtr() );
106 m_xStyleExportMapper = new OFormComponentStyleExportMapper( xStylePropertiesMapper.getBodyPtr() );
108 // our style family
109 m_rContext.GetAutoStylePool()->AddFamily(
110 XML_STYLE_FAMILY_CONTROL_ID, token::GetXMLToken(token::XML_PARAGRAPH),
111 m_xStyleExportMapper.getBodyPtr(),
112 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XML_STYLE_FAMILY_CONTROL_PREFIX) )
115 // add our event translation table
116 m_rContext.GetEventExport().AddTranslationTable(g_pFormsEventTranslation);
118 clear();
121 OFormLayerXMLExport_Impl::~OFormLayerXMLExport_Impl()
125 //---------------------------------------------------------------------
126 sal_Bool OFormLayerXMLExport_Impl::impl_isFormPageContainingForms(const Reference< XDrawPage >& _rxDrawPage, Reference< XIndexAccess >& _rxForms)
128 Reference< XFormsSupplier2 > xFormsSupp(_rxDrawPage, UNO_QUERY);
129 OSL_ENSURE(xFormsSupp.is(), "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid draw page (no XFormsSupplier)! Doin' nothing!");
130 if (!xFormsSupp.is())
131 return sal_False;
133 if ( !xFormsSupp->hasForms() )
134 // nothing to do at all
135 return sal_False;
137 _rxForms = Reference< XIndexAccess >(xFormsSupp->getForms(), UNO_QUERY);
138 Reference< XServiceInfo > xSI(_rxForms, UNO_QUERY); // order is important!
139 OSL_ENSURE(xSI.is(), "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (must not be NULL and must have a ServiceInfo)!");
140 if (!xSI.is())
141 return sal_False;
143 if (!xSI->supportsService(SERVICE_FORMSCOLLECTION))
145 OSL_ENSURE(sal_False, "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (is no com.sun.star.form.Forms)!");
146 // nothing to do
147 return sal_False;
149 return sal_True;
152 //---------------------------------------------------------------------
153 void OFormLayerXMLExport_Impl::exportGridColumn(const Reference< XPropertySet >& _rxColumn,
154 const Sequence< ScriptEventDescriptor >& _rEvents)
156 // do the exporting
157 OColumnExport aExportImpl(*this, _rxColumn, getControlId( _rxColumn ), _rEvents);
158 aExportImpl.doExport();
161 //---------------------------------------------------------------------
162 void OFormLayerXMLExport_Impl::exportControl(const Reference< XPropertySet >& _rxControl,
163 const Sequence< ScriptEventDescriptor >& _rEvents)
165 // the list of the referring controls
166 ::rtl::OUString sReferringControls;
167 MapPropertySet2String::const_iterator aReferring = m_aCurrentPageReferring->second.find(_rxControl);
168 if (aReferring != m_aCurrentPageReferring->second.end())
169 sReferringControls = aReferring->second;
171 // the control id (should already have been created in examineForms)
172 ::rtl::OUString sControlId( getControlId( _rxControl ) );
174 // do the exporting
175 OControlExport aExportImpl(*this, _rxControl, sControlId, sReferringControls, _rEvents);
176 aExportImpl.doExport();
179 //---------------------------------------------------------------------
180 void OFormLayerXMLExport_Impl::exportForm(const Reference< XPropertySet >& _rxProps,
181 const Sequence< ScriptEventDescriptor >& _rEvents)
183 OSL_ENSURE(_rxProps.is(), "OFormLayerXMLExport_Impl::exportForm: invalid property set!");
184 OFormExport aAttributeHandler(*this, _rxProps, _rEvents);
185 aAttributeHandler.doExport();
188 //---------------------------------------------------------------------
189 ::vos::ORef< SvXMLExportPropertyMapper > OFormLayerXMLExport_Impl::getStylePropertyMapper()
191 return m_xStyleExportMapper;
194 //---------------------------------------------------------------------
195 SvXMLExport& OFormLayerXMLExport_Impl::getGlobalContext()
197 return m_rContext;
200 //---------------------------------------------------------------------
201 void OFormLayerXMLExport_Impl::exportCollectionElements(const Reference< XIndexAccess >& _rxCollection)
203 // step through all the elements of the collection
204 sal_Int32 nElements = _rxCollection->getCount();
206 Reference< XEventAttacherManager > xElementEventManager(_rxCollection, UNO_QUERY);
207 Sequence< ScriptEventDescriptor > aElementEvents;
209 Reference< XPropertySetInfo > xPropsInfo;
210 Reference< XIndexAccess > xCurrentContainer;
211 for (sal_Int32 i=0; i<nElements; ++i)
215 // extract the current element
216 Reference< XPropertySet > xCurrentProps( _rxCollection->getByIndex(i), UNO_QUERY );
217 OSL_ENSURE(xCurrentProps.is(), "OFormLayerXMLExport_Impl::exportCollectionElements: invalid child element, skipping!");
218 if (!xCurrentProps.is())
219 continue;
221 // check if there is a ClassId property on the current element. If so, we assume it to be a control
222 xPropsInfo = xCurrentProps->getPropertySetInfo();
223 OSL_ENSURE(xPropsInfo.is(), "OFormLayerXMLExport_Impl::exportCollectionElements: no property set info!");
224 if (!xPropsInfo.is())
225 // without this, a lot of stuff in the export routines may fail
226 continue;
228 // if the element is part of a ignore list, we are not allowed to export it
229 if ( m_aIgnoreList.end() != m_aIgnoreList.find( xCurrentProps ) )
230 continue;
232 if (xElementEventManager.is())
233 aElementEvents = xElementEventManager->getScriptEvents(i);
235 if (xPropsInfo->hasPropertyByName(PROPERTY_COLUMNSERVICENAME))
237 exportGridColumn(xCurrentProps, aElementEvents);
239 else if (xPropsInfo->hasPropertyByName(PROPERTY_CLASSID))
241 exportControl(xCurrentProps, aElementEvents);
243 else
245 exportForm(xCurrentProps, aElementEvents);
248 catch(Exception&)
250 OSL_ENSURE(sal_False, "OFormLayerXMLExport_Impl::exportCollectionElements: caught an exception ... skipping the current element!");
251 continue;
256 //---------------------------------------------------------------------
257 ::rtl::OUString OFormLayerXMLExport_Impl::getObjectStyleName( const Reference< XPropertySet >& _rxObject )
259 ::rtl::OUString aObjectStyle;
261 MapPropertySet2String::const_iterator aObjectStylePos = m_aGridColumnStyles.find( _rxObject );
262 if ( m_aGridColumnStyles.end() != aObjectStylePos )
263 aObjectStyle = aObjectStylePos->second;
264 return aObjectStyle;
267 //---------------------------------------------------------------------
268 void OFormLayerXMLExport_Impl::clear()
270 m_aControlIds.clear();
271 m_aReferringControls.clear();
272 m_aCurrentPageIds = m_aControlIds.end();
273 m_aCurrentPageReferring = m_aReferringControls.end();
275 m_aControlNumberFormats.clear();
276 m_aGridColumnStyles.clear();
278 m_aIgnoreList.clear();
281 //---------------------------------------------------------------------
282 void OFormLayerXMLExport_Impl::exportControlNumberStyles()
284 if (m_pControlNumberStyles)
285 m_pControlNumberStyles->Export(sal_False);
288 //---------------------------------------------------------------------
289 void OFormLayerXMLExport_Impl::exportAutoControlNumberStyles()
291 if ( m_pControlNumberStyles )
292 m_pControlNumberStyles->Export( sal_True );
295 //---------------------------------------------------------------------
296 void OFormLayerXMLExport_Impl::exportAutoStyles()
298 m_rContext.GetAutoStylePool()->exportXML(
299 XML_STYLE_FAMILY_CONTROL_ID,
300 m_rContext.GetDocHandler(),
301 m_rContext.GetMM100UnitConverter(),
302 m_rContext.GetNamespaceMap()
306 //---------------------------------------------------------------------
307 void OFormLayerXMLExport_Impl::exportForms(const Reference< XDrawPage >& _rxDrawPage)
309 // get the forms collection of the page
310 Reference< XIndexAccess > xCollectionIndex;
311 if (!impl_isFormPageContainingForms(_rxDrawPage, xCollectionIndex))
312 return;
314 #if OSL_DEBUG_LEVEL > 0
315 sal_Bool bPageIsKnown =
316 #endif
317 implMoveIterators(_rxDrawPage, sal_False);
318 OSL_ENSURE(bPageIsKnown, "OFormLayerXMLExport_Impl::exportForms: exporting a page which has not been examined!");
320 // export forms collection
321 exportCollectionElements(xCollectionIndex);
324 //---------------------------------------------------------------------
325 void OFormLayerXMLExport_Impl::exportXForms() const
327 // export XForms models
328 ::exportXForms( m_rContext );
331 //---------------------------------------------------------------------
332 bool OFormLayerXMLExport_Impl::pageContainsForms( const Reference< XDrawPage >& _rxDrawPage ) const
334 Reference< XFormsSupplier2 > xFormsSupp( _rxDrawPage, UNO_QUERY );
335 DBG_ASSERT( xFormsSupp.is(), "OFormLayerXMLExport_Impl::pageContainsForms: no XFormsSupplier2!" );
336 return xFormsSupp.is() && xFormsSupp->hasForms();
339 //---------------------------------------------------------------------
340 bool OFormLayerXMLExport_Impl::documentContainsXForms() const
342 Reference< XXFormsSupplier > xXFormSupp( m_rContext.GetModel(), UNO_QUERY );
343 Reference< XNameContainer > xForms;
344 if ( xXFormSupp.is() )
345 xForms = xXFormSupp->getXForms();
346 return xForms.is() && xForms->hasElements();
349 //---------------------------------------------------------------------
350 sal_Bool OFormLayerXMLExport_Impl::implMoveIterators(const Reference< XDrawPage >& _rxDrawPage, sal_Bool _bClear)
352 sal_Bool bKnownPage = sal_False;
354 // the one for the ids
355 m_aCurrentPageIds = m_aControlIds.find(_rxDrawPage);
356 if (m_aControlIds.end() == m_aCurrentPageIds)
358 m_aControlIds[_rxDrawPage] = MapPropertySet2String();
359 m_aCurrentPageIds = m_aControlIds.find(_rxDrawPage);
361 else
363 bKnownPage = sal_True;
364 if (_bClear && !m_aCurrentPageIds->second.empty() )
365 m_aCurrentPageIds->second.clear();
368 // the one for the ids of the referring controls
369 m_aCurrentPageReferring = m_aReferringControls.find(_rxDrawPage);
370 if (m_aReferringControls.end() == m_aCurrentPageReferring)
372 m_aReferringControls[_rxDrawPage] = MapPropertySet2String();
373 m_aCurrentPageReferring = m_aReferringControls.find(_rxDrawPage);
375 else
377 bKnownPage = sal_True;
378 if (_bClear && !m_aCurrentPageReferring->second.empty() )
379 m_aCurrentPageReferring->second.clear();
381 return bKnownPage;
384 //---------------------------------------------------------------------
385 sal_Bool OFormLayerXMLExport_Impl::seekPage(const Reference< XDrawPage >& _rxDrawPage)
387 sal_Bool bKnownPage = implMoveIterators( _rxDrawPage, sal_False );
388 if ( bKnownPage )
389 return sal_True;
391 // if the page is not yet known, this does not automatically mean that it has
392 // not been examined. Instead, examineForms returns silently and successfully
393 // if a page is a XFormsPageSupplier2, but does not have a forms collection
394 // (This behaviour of examineForms is a performance optimization, to not force
395 // the page to create a forms container just to see that it's empty.)
397 // So, in such a case, seekPage is considered to be successfull, too, though the
398 // page was not yet known
399 Reference< XFormsSupplier2 > xFormsSupp( _rxDrawPage, UNO_QUERY );
400 if ( xFormsSupp.is() && !xFormsSupp->hasForms() )
401 return sal_True;
403 // anything else means that the page has not been examined before, or it's no
404 // valid form page. Both cases are Bad (TM).
405 return sal_False;
408 //---------------------------------------------------------------------
409 ::rtl::OUString OFormLayerXMLExport_Impl::getControlId(const Reference< XPropertySet >& _rxControl)
411 OSL_ENSURE(m_aCurrentPageIds != m_aControlIds.end(), "OFormLayerXMLExport_Impl::getControlId: invalid current page!");
412 OSL_ENSURE(m_aCurrentPageIds->second.end() != m_aCurrentPageIds->second.find(_rxControl),
413 "OFormLayerXMLExport_Impl::getControlId: can not find the control!");
414 return m_aCurrentPageIds->second[_rxControl];
417 //---------------------------------------------------------------------
418 ::rtl::OUString OFormLayerXMLExport_Impl::getImmediateNumberStyle( const Reference< XPropertySet >& _rxObject )
420 ::rtl::OUString sNumberStyle;
422 sal_Int32 nOwnFormatKey = implExamineControlNumberFormat( _rxObject );
423 if ( -1 != nOwnFormatKey )
424 sNumberStyle = getControlNumberStyleExport()->GetStyleName( nOwnFormatKey );
426 return sNumberStyle;
429 //---------------------------------------------------------------------
430 ::rtl::OUString OFormLayerXMLExport_Impl::getControlNumberStyle( const Reference< XPropertySet >& _rxControl )
432 ::rtl::OUString sNumberStyle;
434 ConstMapPropertySet2IntIterator aControlFormatPos = m_aControlNumberFormats.find(_rxControl);
435 if (m_aControlNumberFormats.end() != aControlFormatPos)
437 OSL_ENSURE(m_pControlNumberStyles, "OFormLayerXMLExport_Impl::getControlNumberStyle: have a control which has a format style, but no style exporter!");
438 sNumberStyle = getControlNumberStyleExport()->GetStyleName(aControlFormatPos->second);
440 // it's allowed to ask for a control which does not have format information.
441 // (This is for performance reasons)
443 return sNumberStyle;
446 //---------------------------------------------------------------------
447 void OFormLayerXMLExport_Impl::examineForms(const Reference< XDrawPage >& _rxDrawPage)
449 // get the forms collection of the page
450 Reference< XIndexAccess > xCollectionIndex;
451 if (!impl_isFormPageContainingForms(_rxDrawPage, xCollectionIndex))
452 return;
454 // move the iterator which specify the currently handled page
455 #if OSL_DEBUG_LEVEL > 0
456 sal_Bool bPageIsKnown =
457 #endif
458 implMoveIterators(_rxDrawPage, sal_True);
459 OSL_ENSURE(!bPageIsKnown, "OFormLayerXMLExport_Impl::examineForms: examining a page twice!");
461 ::std::stack< Reference< XIndexAccess > > aContainerHistory;
462 ::std::stack< sal_Int32 > aIndexHistory;
464 Reference< XIndexAccess > xLoop = xCollectionIndex;
465 sal_Int32 nChildPos = 0;
468 if (nChildPos < xLoop->getCount())
470 Reference< XPropertySet > xCurrent( xLoop->getByIndex( nChildPos ), UNO_QUERY );
471 OSL_ENSURE(xCurrent.is(), "OFormLayerXMLExport_Impl::examineForms: invalid child object");
472 if (!xCurrent.is())
473 continue;
475 if (!checkExamineControl(xCurrent))
477 // step down
478 Reference< XIndexAccess > xNextContainer(xCurrent, UNO_QUERY);
479 OSL_ENSURE(xNextContainer.is(), "OFormLayerXMLExport_Impl::examineForms: what the heck is this ... no control, no container?");
480 aContainerHistory.push(xLoop);
481 aIndexHistory.push(nChildPos);
483 xLoop = xNextContainer;
484 nChildPos = -1; // will be incremented below
486 ++nChildPos;
488 else
490 // step up
491 while ((nChildPos >= xLoop->getCount()) && !aContainerHistory.empty() )
493 xLoop = aContainerHistory.top();
494 aContainerHistory.pop();
495 nChildPos = aIndexHistory.top();
496 aIndexHistory.pop();
498 ++nChildPos;
500 if (nChildPos >= xLoop->getCount())
501 // exited the loop above because we have no history anymore (0 == aContainerHistory.size()),
502 // and on the current level there are no more children
503 // -> leave
504 break;
507 while (xLoop.is());
510 //---------------------------------------------------------------------
511 namespace
513 struct AccumulateSize : public ::std::binary_function< size_t, MapPropertySet2Map::value_type, size_t >
515 size_t operator()( size_t _size, const MapPropertySet2Map::value_type& _map ) const
517 return _size + _map.second.size();
521 ::rtl::OUString lcl_findFreeControlId( const MapPropertySet2Map& _rAllPagesControlIds )
523 static const ::rtl::OUString sControlIdBase( RTL_CONSTASCII_USTRINGPARAM( "control" ) );
524 ::rtl::OUString sControlId = sControlIdBase;
526 size_t nKnownControlCount = ::std::accumulate( _rAllPagesControlIds.begin(), _rAllPagesControlIds.end(), (size_t)0, AccumulateSize() );
527 sControlId += ::rtl::OUString::valueOf( (sal_Int32)nKnownControlCount + 1 );
529 #ifdef DBG_UTIL
530 // Check if the id is already used. It shouldn't, as we currently have no mechanism for removing entries
531 // from the map, so the approach used above (take the accumulated map size) should be sufficient. But if
532 // somebody changes this (e.g. allows removing entries from the map), the assertion below probably will fail.
533 for ( MapPropertySet2Map::const_iterator outer = _rAllPagesControlIds.begin();
534 outer != _rAllPagesControlIds.end();
535 ++outer
537 for ( MapPropertySet2String::const_iterator inner = outer->second.begin();
538 inner != outer->second.end();
539 ++inner
542 OSL_ENSURE( inner->second != sControlId,
543 "lcl_findFreeControlId: auto-generated control ID is already used!" );
545 #endif
546 return sControlId;
550 //---------------------------------------------------------------------
551 sal_Bool OFormLayerXMLExport_Impl::checkExamineControl(const Reference< XPropertySet >& _rxObject)
553 Reference< XPropertySetInfo > xCurrentInfo = _rxObject->getPropertySetInfo();
554 OSL_ENSURE(xCurrentInfo.is(), "OFormLayerXMLExport_Impl::checkExamineControl: no property set info");
556 sal_Bool bIsControl = xCurrentInfo->hasPropertyByName( PROPERTY_CLASSID );
557 if (bIsControl)
559 // ----------------------------------
560 // generate a new control id
562 // find a free id
563 ::rtl::OUString sCurrentId = lcl_findFreeControlId( m_aControlIds );
564 // add it to the map
565 m_aCurrentPageIds->second[_rxObject] = sCurrentId;
567 // ----------------------------------
568 // check if this control has a "LabelControl" property referring another control
569 if ( xCurrentInfo->hasPropertyByName( PROPERTY_CONTROLLABEL ) )
571 Reference< XPropertySet > xCurrentReference( _rxObject->getPropertyValue( PROPERTY_CONTROLLABEL ), UNO_QUERY );
572 if (xCurrentReference.is())
574 ::rtl::OUString& sReferencedBy = m_aCurrentPageReferring->second[xCurrentReference];
575 if (sReferencedBy.getLength())
576 // it's not the first _rxObject referring to the xCurrentReference
577 // -> separate the id
578 sReferencedBy += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
579 sReferencedBy += sCurrentId;
583 // ----------------------------------
584 // check if the control needs a number format style
585 if ( xCurrentInfo->hasPropertyByName( PROPERTY_FORMATKEY ) )
587 examineControlNumberFormat(_rxObject);
590 // ----------------------------------
591 // check if it's a control providing text
592 Reference< XText > xControlText( _rxObject, UNO_QUERY );
593 if ( xControlText.is() )
595 m_rContext.GetTextParagraphExport()->collectTextAutoStyles( xControlText );
598 // ----------------------------------
599 // check if it is a grid control - in this case, we need special handling for the columns
600 sal_Int16 nControlType = FormComponentType::CONTROL;
601 _rxObject->getPropertyValue( PROPERTY_CLASSID ) >>= nControlType;
602 if ( FormComponentType::GRIDCONTROL == nControlType )
604 collectGridColumnStylesAndIds( _rxObject );
608 return bIsControl;
611 //---------------------------------------------------------------------
612 void OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds( const Reference< XPropertySet >& _rxControl )
614 // loop through all columns of the grid
617 Reference< XIndexAccess > xContainer( _rxControl, UNO_QUERY );
618 OSL_ENSURE( xContainer.is(), "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: grid control not being a container?!" );
619 if ( !xContainer.is() )
620 return;
622 Reference< XPropertySetInfo > xColumnPropertiesMeta;
624 sal_Int32 nCount = xContainer->getCount();
625 for ( sal_Int32 i=0; i<nCount; ++i )
627 Reference< XPropertySet > xColumnProperties( xContainer->getByIndex( i ), UNO_QUERY );
628 OSL_ENSURE( xColumnProperties.is(), "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: invalid grid column encountered!" );
629 if ( !xColumnProperties.is() )
630 continue;
632 // ----------------------------------
633 // generate a new control id
635 // find a free id
636 ::rtl::OUString sCurrentId = lcl_findFreeControlId( m_aControlIds );
637 // add it to the map
638 m_aCurrentPageIds->second[ xColumnProperties ] = sCurrentId;
640 // ----------------------------------
641 // determine a number style, if needed
642 xColumnPropertiesMeta = xColumnProperties->getPropertySetInfo();
643 // get the styles of the column
644 ::std::vector< XMLPropertyState > aPropertyStates = m_xStyleExportMapper->Filter( xColumnProperties );
646 // care for the number format, additionally
647 ::rtl::OUString sColumnNumberStyle;
648 if ( xColumnPropertiesMeta.is() && xColumnPropertiesMeta->hasPropertyByName( PROPERTY_FORMATKEY ) )
649 sColumnNumberStyle = getImmediateNumberStyle( xColumnProperties );
651 if ( sColumnNumberStyle.getLength() )
652 { // the column indeed has a formatting
653 sal_Int32 nStyleMapIndex = m_xStyleExportMapper->getPropertySetMapper()->FindEntryIndex( CTF_FORMS_DATA_STYLE );
654 // TODO: move this to the ctor
655 OSL_ENSURE ( -1 != nStyleMapIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for our context id!");
657 XMLPropertyState aNumberStyleState( nStyleMapIndex, makeAny( sColumnNumberStyle ) );
658 aPropertyStates.push_back( aNumberStyleState );
661 #if OSL_DEBUG_LEVEL > 0
662 ::std::vector< XMLPropertyState >::const_iterator aHaveALook = aPropertyStates.begin();
663 for ( ; aHaveALook != aPropertyStates.end(); ++aHaveALook )
665 (void)aHaveALook;
667 #endif
669 // ----------------------------------
670 // determine the column style
672 if ( !aPropertyStates.empty() )
673 { // add to the style pool
674 ::rtl::OUString sColumnStyleName = m_rContext.GetAutoStylePool()->Add( XML_STYLE_FAMILY_CONTROL_ID, aPropertyStates );
676 OSL_ENSURE( m_aGridColumnStyles.end() == m_aGridColumnStyles.find( xColumnProperties ),
677 "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: already have a style for this column!" );
679 m_aGridColumnStyles.insert( MapPropertySet2String::value_type( xColumnProperties, sColumnStyleName ) );
683 catch( const Exception& )
685 DBG_UNHANDLED_EXCEPTION();
689 //---------------------------------------------------------------------
690 sal_Int32 OFormLayerXMLExport_Impl::implExamineControlNumberFormat( const Reference< XPropertySet >& _rxObject )
692 // get the format key relative to our own formats supplier
693 sal_Int32 nOwnFormatKey = ensureTranslateFormat( _rxObject );
695 if ( -1 != nOwnFormatKey )
696 // tell the exporter that we used this format
697 getControlNumberStyleExport()->SetUsed( nOwnFormatKey );
699 return nOwnFormatKey;
702 //---------------------------------------------------------------------
703 void OFormLayerXMLExport_Impl::examineControlNumberFormat( const Reference< XPropertySet >& _rxControl )
705 sal_Int32 nOwnFormatKey = implExamineControlNumberFormat( _rxControl );
707 if ( -1 == nOwnFormatKey )
708 // nothing to do, the number format of this control is void
709 return;
711 // remember the format key for this control (we'll be asked in getControlNumberStyle for this)
712 OSL_ENSURE(m_aControlNumberFormats.end() == m_aControlNumberFormats.find(_rxControl),
713 "OFormLayerXMLExport_Impl::examineControlNumberFormat: already handled this control!");
714 m_aControlNumberFormats[_rxControl] = nOwnFormatKey;
717 //---------------------------------------------------------------------
718 sal_Int32 OFormLayerXMLExport_Impl::ensureTranslateFormat(const Reference< XPropertySet >& _rxFormattedControl)
720 ensureControlNumberStyleExport();
721 OSL_ENSURE(m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: no own formats supplier!");
722 // (should have been created in ensureControlNumberStyleExport)
724 sal_Int32 nOwnFormatKey = -1;
726 // the format key (relative to the control's supplier)
727 sal_Int32 nControlFormatKey = -1;
728 Any aControlFormatKey = _rxFormattedControl->getPropertyValue(PROPERTY_FORMATKEY);
729 if (aControlFormatKey >>= nControlFormatKey)
731 // the control's number format
732 Reference< XNumberFormatsSupplier > xControlFormatsSupplier;
733 _rxFormattedControl->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xControlFormatsSupplier;
734 Reference< XNumberFormats > xControlFormats;
735 if (xControlFormatsSupplier.is())
736 xControlFormats = xControlFormatsSupplier->getNumberFormats();
737 OSL_ENSURE(xControlFormats.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: formatted control without supplier!");
739 // obtain the persistent (does not depend on the formats supplier) representation of the control's format
740 Locale aFormatLocale;
741 ::rtl::OUString sFormatDescription;
742 if (xControlFormats.is())
744 Reference< XPropertySet > xControlFormat = xControlFormats->getByKey(nControlFormatKey);
746 xControlFormat->getPropertyValue(PROPERTY_LOCALE) >>= aFormatLocale;
747 xControlFormat->getPropertyValue(PROPERTY_FORMATSTRING) >>= sFormatDescription;
750 // check if our own formats collection already knows the format
751 nOwnFormatKey = m_xControlNumberFormats->queryKey(sFormatDescription, aFormatLocale, sal_False);
752 if (-1 == nOwnFormatKey)
753 { // no, we don't
754 // -> create a new format
755 nOwnFormatKey = m_xControlNumberFormats->addNew(sFormatDescription, aFormatLocale);
757 OSL_ENSURE(-1 != nOwnFormatKey, "OFormLayerXMLExport_Impl::ensureTranslateFormat: could not translate the controls format key!");
759 else
760 OSL_ENSURE(!aControlFormatKey.hasValue(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: invalid number format property value!");
762 return nOwnFormatKey;
765 //---------------------------------------------------------------------
766 void OFormLayerXMLExport_Impl::ensureControlNumberStyleExport()
768 if (!m_pControlNumberStyles)
770 // create our number formats supplier (if necessary)
771 Reference< XNumberFormatsSupplier > xFormatsSupplier;
773 OSL_ENSURE(!m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: inconsistence!");
774 // the m_xControlNumberFormats and m_pControlNumberStyles should be maintained together
778 // create it for en-US (does not really matter, as we will specify a locale for every
779 // concrete language to use)
780 Sequence< Any > aSupplierArgs(1);
781 aSupplierArgs[0] <<= Locale ( ::rtl::OUString::createFromAscii("en"),
782 ::rtl::OUString::createFromAscii("US"),
783 ::rtl::OUString()
785 // #110680#
786 //Reference< XInterface > xFormatsSupplierUntyped =
787 // ::comphelper::getProcessServiceFactory()->createInstanceWithArguments(
788 // SERVICE_NUMBERFORMATSSUPPLIER,
789 // aSupplierArgs
790 // );
791 Reference< XInterface > xFormatsSupplierUntyped =
792 m_rContext.getServiceFactory()->createInstanceWithArguments(
793 SERVICE_NUMBERFORMATSSUPPLIER,
794 aSupplierArgs
796 OSL_ENSURE(xFormatsSupplierUntyped.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: could not instantiate a number formats supplier!");
798 xFormatsSupplier = Reference< XNumberFormatsSupplier >(xFormatsSupplierUntyped, UNO_QUERY);
799 if (xFormatsSupplier.is())
800 m_xControlNumberFormats = xFormatsSupplier->getNumberFormats();
802 catch(const Exception&)
806 OSL_ENSURE(m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: could not obtain my default number formats!");
808 // create the exporter
809 m_pControlNumberStyles = new SvXMLNumFmtExport(m_rContext, xFormatsSupplier, getControlNumberStyleNamePrefix());
813 //---------------------------------------------------------------------
814 SvXMLNumFmtExport* OFormLayerXMLExport_Impl::getControlNumberStyleExport()
816 ensureControlNumberStyleExport();
817 return m_pControlNumberStyles;
820 //---------------------------------------------------------------------
821 void OFormLayerXMLExport_Impl::excludeFromExport( const Reference< XControlModel > _rxControl )
823 Reference< XPropertySet > xProps( _rxControl, UNO_QUERY );
824 OSL_ENSURE( xProps.is(), "OFormLayerXMLExport_Impl::excludeFromExport: invalid control model!" );
825 #if OSL_DEBUG_LEVEL > 0
826 ::std::pair< PropertySetBag::iterator, bool > aPos =
827 #endif
828 m_aIgnoreList.insert( xProps );
829 OSL_ENSURE( aPos.second, "OFormLayerXMLExport_Impl::excludeFromExport: element already exists in the ignore list!" );
832 //.........................................................................
833 } // namespace xmloff
834 //.........................................................................