1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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"
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 === **/
68 //.........................................................................
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() );
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
);
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())
133 if ( !xFormsSupp
->hasForms() )
134 // nothing to do at all
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)!");
143 if (!xSI
->supportsService(SERVICE_FORMSCOLLECTION
))
145 OSL_ENSURE(sal_False
, "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (is no com.sun.star.form.Forms)!");
152 //---------------------------------------------------------------------
153 void OFormLayerXMLExport_Impl::exportGridColumn(const Reference
< XPropertySet
>& _rxColumn
,
154 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
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
) );
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()
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())
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
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
) )
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
);
245 exportForm(xCurrentProps
, aElementEvents
);
250 OSL_ENSURE(sal_False
, "OFormLayerXMLExport_Impl::exportCollectionElements: caught an exception ... skipping the current element!");
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
;
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
))
314 #if OSL_DEBUG_LEVEL > 0
315 sal_Bool bPageIsKnown
=
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
);
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
);
377 bKnownPage
= sal_True
;
378 if (_bClear
&& !m_aCurrentPageReferring
->second
.empty() )
379 m_aCurrentPageReferring
->second
.clear();
384 //---------------------------------------------------------------------
385 sal_Bool
OFormLayerXMLExport_Impl::seekPage(const Reference
< XDrawPage
>& _rxDrawPage
)
387 sal_Bool bKnownPage
= implMoveIterators( _rxDrawPage
, sal_False
);
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() )
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).
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
);
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)
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
))
454 // move the iterator which specify the currently handled page
455 #if OSL_DEBUG_LEVEL > 0
456 sal_Bool bPageIsKnown
=
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");
475 if (!checkExamineControl(xCurrent
))
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
491 while ((nChildPos
>= xLoop
->getCount()) && !aContainerHistory
.empty() )
493 xLoop
= aContainerHistory
.top();
494 aContainerHistory
.pop();
495 nChildPos
= aIndexHistory
.top();
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
510 //---------------------------------------------------------------------
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 );
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();
537 for ( MapPropertySet2String::const_iterator inner
= outer
->second
.begin();
538 inner
!= outer
->second
.end();
542 OSL_ENSURE( inner
->second
!= sControlId
,
543 "lcl_findFreeControlId: auto-generated control ID is already used!" );
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
);
559 // ----------------------------------
560 // generate a new control id
563 ::rtl::OUString sCurrentId
= lcl_findFreeControlId( m_aControlIds
);
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
);
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() )
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() )
632 // ----------------------------------
633 // generate a new control id
636 ::rtl::OUString sCurrentId
= lcl_findFreeControlId( m_aControlIds
);
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
)
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
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
)
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!");
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"),
786 //Reference< XInterface > xFormatsSupplierUntyped =
787 // ::comphelper::getProcessServiceFactory()->createInstanceWithArguments(
788 // SERVICE_NUMBERFORMATSSUPPLIER,
791 Reference
< XInterface
> xFormatsSupplierUntyped
=
792 m_rContext
.getServiceFactory()->createInstanceWithArguments(
793 SERVICE_NUMBERFORMATSSUPPLIER
,
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
=
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 //.........................................................................