1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "layerexport.hxx"
21 #include "strings.hxx"
22 #include <xmloff/xmlexp.hxx>
23 #include <xmloff/nmspmap.hxx>
24 #include <xmloff/xmlnmspe.hxx>
25 #include <xmloff/xmluconv.hxx>
26 #include <xmloff/xmlprmap.hxx>
27 #include <xmloff/prhdlfac.hxx>
28 #include "elementexport.hxx"
29 #include <xmloff/families.hxx>
30 #include <xmloff/contextid.hxx>
31 #include <xmloff/controlpropertyhdl.hxx>
32 #include <xmloff/maptype.hxx>
33 #include <tools/diagnose_ex.h>
34 #include <tools/debug.hxx>
35 #include "controlpropertymap.hxx"
36 #include <com/sun/star/container/XIndexAccess.hpp>
37 #include <com/sun/star/form/XFormsSupplier2.hpp>
38 #include <com/sun/star/xforms/XFormsSupplier.hpp>
39 #include <com/sun/star/form/FormComponentType.hpp>
40 #include <com/sun/star/lang/XServiceInfo.hpp>
41 #include <com/sun/star/container/XChild.hpp>
42 #include <com/sun/star/script/XEventAttacherManager.hpp>
43 #include <com/sun/star/util/NumberFormatsSupplier.hpp>
44 #include "eventexport.hxx"
45 #include <xmloff/XMLEventExport.hxx>
46 #include "formevents.hxx"
47 #include <xmloff/xmlnumfe.hxx>
48 #include <xmloff/xformsexport.hxx>
49 #include <comphelper/processfactory.hxx>
51 #include <com/sun/star/text/XText.hpp>
58 using namespace ::com::sun::star::uno
;
59 using namespace ::com::sun::star::awt
;
60 using namespace ::com::sun::star::lang
;
61 using namespace ::com::sun::star::beans
;
62 using namespace ::com::sun::star::container
;
63 using namespace ::com::sun::star::drawing
;
64 using namespace ::com::sun::star::form
;
65 using namespace ::com::sun::star::script
;
66 using namespace ::com::sun::star::util
;
67 using namespace ::com::sun::star::text
;
69 typedef ::com::sun::star::xforms::XFormsSupplier XXFormsSupplier
;
71 //= OFormLayerXMLExport_Impl
72 const OUString
& OFormLayerXMLExport_Impl::getControlNumberStyleNamePrefix()
74 static const OUString
s_sControlNumberStyleNamePrefix("C");
75 return s_sControlNumberStyleNamePrefix
;
78 OFormLayerXMLExport_Impl::OFormLayerXMLExport_Impl(SvXMLExport
& _rContext
)
79 :m_rContext(_rContext
)
80 ,m_pControlNumberStyles(NULL
)
82 initializePropertyMaps();
84 // add our style family to the export context's style pool
85 m_xPropertyHandlerFactory
= new OControlPropertyHandlerFactory();
86 ::rtl::Reference
< XMLPropertySetMapper
> xStylePropertiesMapper
= new XMLPropertySetMapper( getControlStylePropertyMap(), m_xPropertyHandlerFactory
.get(), true );
87 m_xStyleExportMapper
= new OFormComponentStyleExportMapper( xStylePropertiesMapper
.get() );
90 m_rContext
.GetAutoStylePool()->AddFamily(
91 XML_STYLE_FAMILY_CONTROL_ID
, token::GetXMLToken(token::XML_PARAGRAPH
),
92 m_xStyleExportMapper
.get(),
93 OUString( XML_STYLE_FAMILY_CONTROL_PREFIX
)
96 // add our event translation table
97 m_rContext
.GetEventExport().AddTranslationTable(g_pFormsEventTranslation
);
102 OFormLayerXMLExport_Impl::~OFormLayerXMLExport_Impl()
106 bool OFormLayerXMLExport_Impl::impl_isFormPageContainingForms(const Reference
< XDrawPage
>& _rxDrawPage
, Reference
< XIndexAccess
>& _rxForms
)
108 Reference
< XFormsSupplier2
> xFormsSupp(_rxDrawPage
, UNO_QUERY
);
109 OSL_ENSURE(xFormsSupp
.is(), "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid draw page (no XFormsSupplier)! Doin' nothing!");
110 if (!xFormsSupp
.is())
113 if ( !xFormsSupp
->hasForms() )
114 // nothing to do at all
117 _rxForms
= Reference
< XIndexAccess
>(xFormsSupp
->getForms(), UNO_QUERY
);
118 Reference
< XServiceInfo
> xSI(_rxForms
, UNO_QUERY
); // order is important!
119 OSL_ENSURE(xSI
.is(), "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (must not be NULL and must have a ServiceInfo)!");
123 if (!xSI
->supportsService("com.sun.star.form.Forms"))
125 OSL_FAIL("OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (is no com.sun.star.form.Forms)!");
132 void OFormLayerXMLExport_Impl::exportGridColumn(const Reference
< XPropertySet
>& _rxColumn
,
133 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
136 OColumnExport
aExportImpl(*this, _rxColumn
, getControlId( _rxColumn
), _rEvents
);
137 aExportImpl
.doExport();
140 void OFormLayerXMLExport_Impl::exportControl(const Reference
< XPropertySet
>& _rxControl
,
141 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
143 // the list of the referring controls
144 OUString sReferringControls
;
145 MapPropertySet2String::const_iterator aReferring
= m_aCurrentPageReferring
->second
.find(_rxControl
);
146 if (aReferring
!= m_aCurrentPageReferring
->second
.end())
147 sReferringControls
= aReferring
->second
;
149 // the control id (should already have been created in examineForms)
150 OUString
sControlId( getControlId( _rxControl
) );
153 OControlExport
aExportImpl(*this, _rxControl
, sControlId
, sReferringControls
, _rEvents
);
154 aExportImpl
.doExport();
157 void OFormLayerXMLExport_Impl::exportForm(const Reference
< XPropertySet
>& _rxProps
,
158 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
160 OSL_ENSURE(_rxProps
.is(), "OFormLayerXMLExport_Impl::exportForm: invalid property set!");
161 OFormExport
aAttributeHandler(*this, _rxProps
, _rEvents
);
162 aAttributeHandler
.doExport();
165 ::rtl::Reference
< SvXMLExportPropertyMapper
> OFormLayerXMLExport_Impl::getStylePropertyMapper()
167 return m_xStyleExportMapper
;
170 SvXMLExport
& OFormLayerXMLExport_Impl::getGlobalContext()
175 void OFormLayerXMLExport_Impl::exportCollectionElements(const Reference
< XIndexAccess
>& _rxCollection
)
177 // step through all the elements of the collection
178 sal_Int32 nElements
= _rxCollection
->getCount();
180 Reference
< XEventAttacherManager
> xElementEventManager(_rxCollection
, UNO_QUERY
);
181 Sequence
< ScriptEventDescriptor
> aElementEvents
;
183 Reference
< XPropertySetInfo
> xPropsInfo
;
184 Reference
< XIndexAccess
> xCurrentContainer
;
185 for (sal_Int32 i
=0; i
<nElements
; ++i
)
189 // extract the current element
190 Reference
< XPropertySet
> xCurrentProps( _rxCollection
->getByIndex(i
), UNO_QUERY
);
191 OSL_ENSURE(xCurrentProps
.is(), "OFormLayerXMLExport_Impl::exportCollectionElements: invalid child element, skipping!");
192 if (!xCurrentProps
.is())
195 // check if there is a ClassId property on the current element. If so, we assume it to be a control
196 xPropsInfo
= xCurrentProps
->getPropertySetInfo();
197 OSL_ENSURE(xPropsInfo
.is(), "OFormLayerXMLExport_Impl::exportCollectionElements: no property set info!");
198 if (!xPropsInfo
.is())
199 // without this, a lot of stuff in the export routines may fail
202 // if the element is part of a ignore list, we are not allowed to export it
203 if ( m_aIgnoreList
.end() != m_aIgnoreList
.find( xCurrentProps
) )
206 if (xElementEventManager
.is())
207 aElementEvents
= xElementEventManager
->getScriptEvents(i
);
209 if (xPropsInfo
->hasPropertyByName(PROPERTY_COLUMNSERVICENAME
))
211 exportGridColumn(xCurrentProps
, aElementEvents
);
213 else if (xPropsInfo
->hasPropertyByName(PROPERTY_CLASSID
))
215 exportControl(xCurrentProps
, aElementEvents
);
219 exportForm(xCurrentProps
, aElementEvents
);
224 OSL_FAIL("OFormLayerXMLExport_Impl::exportCollectionElements: caught an exception ... skipping the current element!");
230 OUString
OFormLayerXMLExport_Impl::getObjectStyleName( const Reference
< XPropertySet
>& _rxObject
)
232 OUString aObjectStyle
;
234 MapPropertySet2String::const_iterator aObjectStylePos
= m_aGridColumnStyles
.find( _rxObject
);
235 if ( m_aGridColumnStyles
.end() != aObjectStylePos
)
236 aObjectStyle
= aObjectStylePos
->second
;
240 void OFormLayerXMLExport_Impl::clear()
242 m_aControlIds
.clear();
243 m_aReferringControls
.clear();
244 m_aCurrentPageIds
= m_aControlIds
.end();
245 m_aCurrentPageReferring
= m_aReferringControls
.end();
247 m_aControlNumberFormats
.clear();
248 m_aGridColumnStyles
.clear();
250 m_aIgnoreList
.clear();
253 void OFormLayerXMLExport_Impl::exportAutoControlNumberStyles()
255 if ( m_pControlNumberStyles
)
256 m_pControlNumberStyles
->Export( true );
259 void OFormLayerXMLExport_Impl::exportAutoStyles()
261 m_rContext
.GetAutoStylePool()->exportXML(
262 XML_STYLE_FAMILY_CONTROL_ID
,
263 m_rContext
.GetDocHandler(),
264 m_rContext
.GetMM100UnitConverter(),
265 m_rContext
.GetNamespaceMap()
269 void OFormLayerXMLExport_Impl::exportForms(const Reference
< XDrawPage
>& _rxDrawPage
)
271 // get the forms collection of the page
272 Reference
< XIndexAccess
> xCollectionIndex
;
273 if (!impl_isFormPageContainingForms(_rxDrawPage
, xCollectionIndex
))
278 #if OSL_DEBUG_LEVEL > 0
281 implMoveIterators(_rxDrawPage
, false);
282 OSL_ENSURE(bPageIsKnown
, "OFormLayerXMLExport_Impl::exportForms: exporting a page which has not been examined!");
284 // export forms collection
285 exportCollectionElements(xCollectionIndex
);
288 void OFormLayerXMLExport_Impl::exportXForms() const
290 // export XForms models
291 ::exportXForms( m_rContext
);
294 bool OFormLayerXMLExport_Impl::pageContainsForms( const Reference
< XDrawPage
>& _rxDrawPage
)
296 Reference
< XFormsSupplier2
> xFormsSupp( _rxDrawPage
, UNO_QUERY
);
297 DBG_ASSERT( xFormsSupp
.is(), "OFormLayerXMLExport_Impl::pageContainsForms: no XFormsSupplier2!" );
298 return xFormsSupp
.is() && xFormsSupp
->hasForms();
301 bool OFormLayerXMLExport_Impl::documentContainsXForms() const
303 Reference
< XXFormsSupplier
> xXFormSupp( m_rContext
.GetModel(), UNO_QUERY
);
304 Reference
< XNameContainer
> xForms
;
305 if ( xXFormSupp
.is() )
306 xForms
= xXFormSupp
->getXForms();
307 return xForms
.is() && xForms
->hasElements();
310 bool OFormLayerXMLExport_Impl::implMoveIterators(const Reference
< XDrawPage
>& _rxDrawPage
, bool _bClear
)
312 if (!_rxDrawPage
.is())
315 bool bKnownPage
= false;
317 // the one for the ids
318 m_aCurrentPageIds
= m_aControlIds
.find(_rxDrawPage
);
319 if (m_aControlIds
.end() == m_aCurrentPageIds
)
321 m_aControlIds
[_rxDrawPage
] = MapPropertySet2String();
322 m_aCurrentPageIds
= m_aControlIds
.find(_rxDrawPage
);
327 if (_bClear
&& !m_aCurrentPageIds
->second
.empty() )
328 m_aCurrentPageIds
->second
.clear();
331 // the one for the ids of the referring controls
332 m_aCurrentPageReferring
= m_aReferringControls
.find(_rxDrawPage
);
333 if (m_aReferringControls
.end() == m_aCurrentPageReferring
)
335 m_aReferringControls
[_rxDrawPage
] = MapPropertySet2String();
336 m_aCurrentPageReferring
= m_aReferringControls
.find(_rxDrawPage
);
341 if (_bClear
&& !m_aCurrentPageReferring
->second
.empty() )
342 m_aCurrentPageReferring
->second
.clear();
347 bool OFormLayerXMLExport_Impl::seekPage(const Reference
< XDrawPage
>& _rxDrawPage
)
349 bool bKnownPage
= implMoveIterators( _rxDrawPage
, false );
353 // if the page is not yet known, this does not automatically mean that it has
354 // not been examined. Instead, examineForms returns silently and successfully
355 // if a page is a XFormsPageSupplier2, but does not have a forms collection
356 // (This behaviour of examineForms is a performance optimization, to not force
357 // the page to create a forms container just to see that it's empty.)
359 // So, in such a case, seekPage is considered to be successful, too, though the
360 // page was not yet known
361 Reference
< XFormsSupplier2
> xFormsSupp( _rxDrawPage
, UNO_QUERY
);
362 if ( xFormsSupp
.is() && !xFormsSupp
->hasForms() )
365 // anything else means that the page has not been examined before, or it's no
366 // valid form page. Both cases are Bad (TM).
370 OUString
OFormLayerXMLExport_Impl::getControlId(const Reference
< XPropertySet
>& _rxControl
)
372 if (m_aCurrentPageIds
== m_aControlIds
.end())
375 OSL_ENSURE(m_aCurrentPageIds
->second
.end() != m_aCurrentPageIds
->second
.find(_rxControl
),
376 "OFormLayerXMLExport_Impl::getControlId: can not find the control!");
377 return m_aCurrentPageIds
->second
[_rxControl
];
380 OUString
OFormLayerXMLExport_Impl::getImmediateNumberStyle( const Reference
< XPropertySet
>& _rxObject
)
382 OUString sNumberStyle
;
384 sal_Int32 nOwnFormatKey
= implExamineControlNumberFormat( _rxObject
);
385 if ( -1 != nOwnFormatKey
)
386 sNumberStyle
= getControlNumberStyleExport()->GetStyleName( nOwnFormatKey
);
391 OUString
OFormLayerXMLExport_Impl::getControlNumberStyle( const Reference
< XPropertySet
>& _rxControl
)
393 OUString sNumberStyle
;
395 MapPropertySet2Int::const_iterator aControlFormatPos
= m_aControlNumberFormats
.find(_rxControl
);
396 if (m_aControlNumberFormats
.end() != aControlFormatPos
)
398 OSL_ENSURE(m_pControlNumberStyles
, "OFormLayerXMLExport_Impl::getControlNumberStyle: have a control which has a format style, but no style exporter!");
399 sNumberStyle
= getControlNumberStyleExport()->GetStyleName(aControlFormatPos
->second
);
401 // it's allowed to ask for a control which does not have format information.
402 // (This is for performance reasons)
407 void OFormLayerXMLExport_Impl::examineForms(const Reference
< XDrawPage
>& _rxDrawPage
)
409 // get the forms collection of the page
410 Reference
< XIndexAccess
> xCollectionIndex
;
411 if (!impl_isFormPageContainingForms(_rxDrawPage
, xCollectionIndex
))
416 // move the iterator which specify the currently handled page
417 #if OSL_DEBUG_LEVEL > 0
420 implMoveIterators(_rxDrawPage
, true);
421 OSL_ENSURE(!bPageIsKnown
, "OFormLayerXMLExport_Impl::examineForms: examining a page twice!");
423 ::std::stack
< Reference
< XIndexAccess
> > aContainerHistory
;
424 ::std::stack
< sal_Int32
> aIndexHistory
;
426 Reference
< XIndexAccess
> xLoop
= xCollectionIndex
;
427 sal_Int32 nChildPos
= 0;
430 if (nChildPos
< xLoop
->getCount())
432 Reference
< XPropertySet
> xCurrent( xLoop
->getByIndex( nChildPos
), UNO_QUERY
);
433 OSL_ENSURE(xCurrent
.is(), "OFormLayerXMLExport_Impl::examineForms: invalid child object");
437 if (!checkExamineControl(xCurrent
))
440 Reference
< XIndexAccess
> xNextContainer(xCurrent
, UNO_QUERY
);
441 OSL_ENSURE(xNextContainer
.is(), "OFormLayerXMLExport_Impl::examineForms: what the heck is this ... no control, no container?");
442 aContainerHistory
.push(xLoop
);
443 aIndexHistory
.push(nChildPos
);
445 xLoop
= xNextContainer
;
446 nChildPos
= -1; // will be incremented below
453 while ((nChildPos
>= xLoop
->getCount()) && !aContainerHistory
.empty() )
455 xLoop
= aContainerHistory
.top();
456 aContainerHistory
.pop();
457 nChildPos
= aIndexHistory
.top();
462 if (nChildPos
>= xLoop
->getCount())
463 // exited the loop above because we have no history anymore (0 == aContainerHistory.size()),
464 // and on the current level there are no more children
474 struct AccumulateSize
: public ::std::binary_function
< size_t, MapPropertySet2Map::value_type
, size_t >
476 size_t operator()( size_t _size
, const MapPropertySet2Map::value_type
& _map
) const
478 return _size
+ _map
.second
.size();
482 OUString
lcl_findFreeControlId( const MapPropertySet2Map
& _rAllPagesControlIds
)
484 static const char sControlIdBase
[] = "control";
485 OUString sControlId
= sControlIdBase
;
487 size_t nKnownControlCount
= ::std::accumulate( _rAllPagesControlIds
.begin(), _rAllPagesControlIds
.end(), (size_t)0, AccumulateSize() );
488 sControlId
+= OUString::number( (sal_Int32
)nKnownControlCount
+ 1 );
491 // Check if the id is already used. It shouldn't, as we currently have no mechanism for removing entries
492 // from the map, so the approach used above (take the accumulated map size) should be sufficient. But if
493 // somebody changes this (e.g. allows removing entries from the map), the assertion below probably will fail.
494 for ( MapPropertySet2Map::const_iterator outer
= _rAllPagesControlIds
.begin();
495 outer
!= _rAllPagesControlIds
.end();
498 for ( MapPropertySet2String::const_iterator inner
= outer
->second
.begin();
499 inner
!= outer
->second
.end();
503 OSL_ENSURE( inner
->second
!= sControlId
,
504 "lcl_findFreeControlId: auto-generated control ID is already used!" );
511 bool OFormLayerXMLExport_Impl::checkExamineControl(const Reference
< XPropertySet
>& _rxObject
)
513 Reference
< XPropertySetInfo
> xCurrentInfo
= _rxObject
->getPropertySetInfo();
514 OSL_ENSURE(xCurrentInfo
.is(), "OFormLayerXMLExport_Impl::checkExamineControl: no property set info");
516 bool bIsControl
= xCurrentInfo
->hasPropertyByName( PROPERTY_CLASSID
);
519 // generate a new control id
522 OUString sCurrentId
= lcl_findFreeControlId( m_aControlIds
);
524 m_aCurrentPageIds
->second
[_rxObject
] = sCurrentId
;
526 // check if this control has a "LabelControl" property referring another control
527 if ( xCurrentInfo
->hasPropertyByName( PROPERTY_CONTROLLABEL
) )
529 Reference
< XPropertySet
> xCurrentReference( _rxObject
->getPropertyValue( PROPERTY_CONTROLLABEL
), UNO_QUERY
);
530 if (xCurrentReference
.is())
532 OUString
& sReferencedBy
= m_aCurrentPageReferring
->second
[xCurrentReference
];
533 if (!sReferencedBy
.isEmpty())
534 // it's not the first _rxObject referring to the xCurrentReference
535 // -> separate the id
536 sReferencedBy
+= ",";
537 sReferencedBy
+= sCurrentId
;
541 // check if the control needs a number format style
542 if ( xCurrentInfo
->hasPropertyByName( PROPERTY_FORMATKEY
) )
544 examineControlNumberFormat(_rxObject
);
547 // check if it's a control providing text
548 Reference
< XText
> xControlText( _rxObject
, UNO_QUERY
);
549 if ( xControlText
.is() )
551 m_rContext
.GetTextParagraphExport()->collectTextAutoStyles( xControlText
);
554 // check if it is a grid control - in this case, we need special handling for the columns
555 sal_Int16 nControlType
= FormComponentType::CONTROL
;
556 _rxObject
->getPropertyValue( PROPERTY_CLASSID
) >>= nControlType
;
557 if ( FormComponentType::GRIDCONTROL
== nControlType
)
559 collectGridColumnStylesAndIds( _rxObject
);
566 void OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds( const Reference
< XPropertySet
>& _rxControl
)
568 // loop through all columns of the grid
571 Reference
< XIndexAccess
> xContainer( _rxControl
, UNO_QUERY
);
572 OSL_ENSURE( xContainer
.is(), "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: grid control not being a container?!" );
573 if ( !xContainer
.is() )
576 Reference
< XPropertySetInfo
> xColumnPropertiesMeta
;
578 sal_Int32 nCount
= xContainer
->getCount();
579 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
581 Reference
< XPropertySet
> xColumnProperties( xContainer
->getByIndex( i
), UNO_QUERY
);
582 OSL_ENSURE( xColumnProperties
.is(), "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: invalid grid column encountered!" );
583 if ( !xColumnProperties
.is() )
586 // generate a new control id
589 OUString sCurrentId
= lcl_findFreeControlId( m_aControlIds
);
591 m_aCurrentPageIds
->second
[ xColumnProperties
] = sCurrentId
;
593 // determine a number style, if needed
594 xColumnPropertiesMeta
= xColumnProperties
->getPropertySetInfo();
595 // get the styles of the column
596 ::std::vector
< XMLPropertyState
> aPropertyStates
= m_xStyleExportMapper
->Filter( xColumnProperties
);
598 // care for the number format, additionally
599 OUString sColumnNumberStyle
;
600 if ( xColumnPropertiesMeta
.is() && xColumnPropertiesMeta
->hasPropertyByName( PROPERTY_FORMATKEY
) )
601 sColumnNumberStyle
= getImmediateNumberStyle( xColumnProperties
);
603 if ( !sColumnNumberStyle
.isEmpty() )
604 { // the column indeed has a formatting
605 sal_Int32 nStyleMapIndex
= m_xStyleExportMapper
->getPropertySetMapper()->FindEntryIndex( CTF_FORMS_DATA_STYLE
);
606 // TODO: move this to the ctor
607 OSL_ENSURE ( -1 != nStyleMapIndex
, "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: could not obtain the index for our context id!");
609 XMLPropertyState
aNumberStyleState( nStyleMapIndex
, makeAny( sColumnNumberStyle
) );
610 aPropertyStates
.push_back( aNumberStyleState
);
613 #if OSL_DEBUG_LEVEL > 0
614 ::std::vector
< XMLPropertyState
>::const_iterator aHaveALook
= aPropertyStates
.begin();
615 for ( ; aHaveALook
!= aPropertyStates
.end(); ++aHaveALook
)
621 // determine the column style
623 if ( !aPropertyStates
.empty() )
624 { // add to the style pool
625 OUString sColumnStyleName
= m_rContext
.GetAutoStylePool()->Add( XML_STYLE_FAMILY_CONTROL_ID
, aPropertyStates
);
627 OSL_ENSURE( m_aGridColumnStyles
.end() == m_aGridColumnStyles
.find( xColumnProperties
),
628 "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: already have a style for this column!" );
630 m_aGridColumnStyles
.insert( MapPropertySet2String::value_type( xColumnProperties
, sColumnStyleName
) );
634 catch( const Exception
& )
636 DBG_UNHANDLED_EXCEPTION();
640 sal_Int32
OFormLayerXMLExport_Impl::implExamineControlNumberFormat( const Reference
< XPropertySet
>& _rxObject
)
642 // get the format key relative to our own formats supplier
643 sal_Int32 nOwnFormatKey
= ensureTranslateFormat( _rxObject
);
645 if ( -1 != nOwnFormatKey
)
646 // tell the exporter that we used this format
647 getControlNumberStyleExport()->SetUsed( nOwnFormatKey
);
649 return nOwnFormatKey
;
652 void OFormLayerXMLExport_Impl::examineControlNumberFormat( const Reference
< XPropertySet
>& _rxControl
)
654 sal_Int32 nOwnFormatKey
= implExamineControlNumberFormat( _rxControl
);
656 if ( -1 == nOwnFormatKey
)
657 // nothing to do, the number format of this control is void
660 // remember the format key for this control (we'll be asked in getControlNumberStyle for this)
661 OSL_ENSURE(m_aControlNumberFormats
.end() == m_aControlNumberFormats
.find(_rxControl
),
662 "OFormLayerXMLExport_Impl::examineControlNumberFormat: already handled this control!");
663 m_aControlNumberFormats
[_rxControl
] = nOwnFormatKey
;
666 sal_Int32
OFormLayerXMLExport_Impl::ensureTranslateFormat(const Reference
< XPropertySet
>& _rxFormattedControl
)
668 ensureControlNumberStyleExport();
669 OSL_ENSURE(m_xControlNumberFormats
.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: no own formats supplier!");
670 // (should have been created in ensureControlNumberStyleExport)
672 sal_Int32 nOwnFormatKey
= -1;
674 // the format key (relative to the control's supplier)
675 sal_Int32 nControlFormatKey
= -1;
676 Any aControlFormatKey
= _rxFormattedControl
->getPropertyValue(PROPERTY_FORMATKEY
);
677 if (aControlFormatKey
>>= nControlFormatKey
)
679 // the control's number format
680 Reference
< XNumberFormatsSupplier
> xControlFormatsSupplier
;
681 _rxFormattedControl
->getPropertyValue(PROPERTY_FORMATSSUPPLIER
) >>= xControlFormatsSupplier
;
682 Reference
< XNumberFormats
> xControlFormats
;
683 if (xControlFormatsSupplier
.is())
684 xControlFormats
= xControlFormatsSupplier
->getNumberFormats();
685 OSL_ENSURE(xControlFormats
.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: formatted control without supplier!");
687 // obtain the persistent (does not depend on the formats supplier) representation of the control's format
688 Locale aFormatLocale
;
689 OUString sFormatDescription
;
690 if (xControlFormats
.is())
692 Reference
< XPropertySet
> xControlFormat
= xControlFormats
->getByKey(nControlFormatKey
);
694 xControlFormat
->getPropertyValue(PROPERTY_LOCALE
) >>= aFormatLocale
;
695 xControlFormat
->getPropertyValue(PROPERTY_FORMATSTRING
) >>= sFormatDescription
;
698 // check if our own formats collection already knows the format
699 nOwnFormatKey
= m_xControlNumberFormats
->queryKey(sFormatDescription
, aFormatLocale
, sal_False
);
700 if (-1 == nOwnFormatKey
)
702 // -> create a new format
703 nOwnFormatKey
= m_xControlNumberFormats
->addNew(sFormatDescription
, aFormatLocale
);
705 OSL_ENSURE(-1 != nOwnFormatKey
, "OFormLayerXMLExport_Impl::ensureTranslateFormat: could not translate the controls format key!");
708 OSL_ENSURE(!aControlFormatKey
.hasValue(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: invalid number format property value!");
710 return nOwnFormatKey
;
713 void OFormLayerXMLExport_Impl::ensureControlNumberStyleExport()
715 if (!m_pControlNumberStyles
)
717 // create our number formats supplier (if necessary)
718 Reference
< XNumberFormatsSupplier
> xFormatsSupplier
;
720 OSL_ENSURE(!m_xControlNumberFormats
.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: inconsistence!");
721 // the m_xControlNumberFormats and m_pControlNumberStyles should be maintained together
725 // create it for en-US (does not really matter, as we will specify a locale for every
726 // concrete language to use)
727 Locale
aLocale ( OUString("en"),
731 xFormatsSupplier
= NumberFormatsSupplier::createWithLocale( m_rContext
.getComponentContext(), aLocale
);
732 m_xControlNumberFormats
= xFormatsSupplier
->getNumberFormats();
734 catch(const Exception
&)
738 OSL_ENSURE(m_xControlNumberFormats
.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: could not obtain my default number formats!");
740 // create the exporter
741 m_pControlNumberStyles
= new SvXMLNumFmtExport(m_rContext
, xFormatsSupplier
, getControlNumberStyleNamePrefix());
745 SvXMLNumFmtExport
* OFormLayerXMLExport_Impl::getControlNumberStyleExport()
747 ensureControlNumberStyleExport();
748 return m_pControlNumberStyles
;
751 void OFormLayerXMLExport_Impl::excludeFromExport( const Reference
< XControlModel
>& _rxControl
)
753 Reference
< XPropertySet
> xProps( _rxControl
, UNO_QUERY
);
754 OSL_ENSURE( xProps
.is(), "OFormLayerXMLExport_Impl::excludeFromExport: invalid control model!" );
755 #if OSL_DEBUG_LEVEL > 0
756 ::std::pair
< PropertySetBag::iterator
, bool > aPos
=
758 m_aIgnoreList
.insert( xProps
);
759 OSL_ENSURE( aPos
.second
, "OFormLayerXMLExport_Impl::excludeFromExport: element already exists in the ignore list!" );
762 } // namespace xmloff
764 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */