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/xmlprmap.hxx>
24 #include <xmloff/prhdlfac.hxx>
25 #include "elementexport.hxx"
26 #include <xmloff/families.hxx>
27 #include <xmloff/contextid.hxx>
28 #include <xmloff/controlpropertyhdl.hxx>
29 #include <xmloff/maptype.hxx>
30 #include <sal/log.hxx>
31 #include <comphelper/diagnose_ex.hxx>
32 #include "controlpropertymap.hxx"
33 #include <com/sun/star/container/XIndexAccess.hpp>
34 #include <com/sun/star/form/XFormsSupplier2.hpp>
35 #include <com/sun/star/frame/XModel.hpp>
36 #include <com/sun/star/xforms/XFormsSupplier.hpp>
37 #include <com/sun/star/form/FormComponentType.hpp>
38 #include <com/sun/star/lang/XServiceInfo.hpp>
39 #include <com/sun/star/script/XEventAttacherManager.hpp>
40 #include <com/sun/star/util/NumberFormatsSupplier.hpp>
41 #include <xmloff/XMLEventExport.hxx>
42 #include "formevents.hxx"
43 #include <xmloff/xmlnumfe.hxx>
44 #include <xmloff/xformsexport.hxx>
46 #include <com/sun/star/text/XText.hpp>
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::awt
;
56 using namespace ::com::sun::star::lang
;
57 using namespace ::com::sun::star::beans
;
58 using namespace ::com::sun::star::container
;
59 using namespace ::com::sun::star::drawing
;
60 using namespace ::com::sun::star::form
;
61 using namespace ::com::sun::star::script
;
62 using namespace ::com::sun::star::util
;
63 using namespace ::com::sun::star::text
;
65 //= OFormLayerXMLExport_Impl
66 const OUString
& OFormLayerXMLExport_Impl::getControlNumberStyleNamePrefix()
68 static const OUString
s_sControlNumberStyleNamePrefix("C");
69 return s_sControlNumberStyleNamePrefix
;
72 OFormLayerXMLExport_Impl::OFormLayerXMLExport_Impl(SvXMLExport
& _rContext
)
73 :m_rContext(_rContext
)
74 ,m_pControlNumberStyles(nullptr)
76 initializePropertyMaps();
78 // add our style family to the export context's style pool
79 m_xPropertyHandlerFactory
= new OControlPropertyHandlerFactory();
80 ::rtl::Reference
< XMLPropertySetMapper
> xStylePropertiesMapper
= new XMLPropertySetMapper( getControlStylePropertyMap(), m_xPropertyHandlerFactory
, true );
81 m_xStyleExportMapper
= new OFormComponentStyleExportMapper( xStylePropertiesMapper
);
84 m_rContext
.GetAutoStylePool()->AddFamily(
85 XmlStyleFamily::CONTROL_ID
, token::GetXMLToken(token::XML_PARAGRAPH
),
86 m_xStyleExportMapper
.get(),
87 OUString( XML_STYLE_FAMILY_CONTROL_PREFIX
)
90 // add our event translation table
91 m_rContext
.GetEventExport().AddTranslationTable(g_pFormsEventTranslation
);
96 OFormLayerXMLExport_Impl::~OFormLayerXMLExport_Impl()
100 bool OFormLayerXMLExport_Impl::impl_isFormPageContainingForms(const Reference
< XDrawPage
>& _rxDrawPage
, Reference
< XIndexAccess
>& _rxForms
)
102 Reference
< XFormsSupplier2
> xFormsSupp(_rxDrawPage
, UNO_QUERY
);
103 OSL_ENSURE(xFormsSupp
.is(), "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid draw page (no XFormsSupplier)! Doin' nothing!");
104 if (!xFormsSupp
.is())
107 if ( !xFormsSupp
->hasForms() )
108 // nothing to do at all
111 _rxForms
.set(xFormsSupp
->getForms(), UNO_QUERY
);
112 Reference
< XServiceInfo
> xSI(_rxForms
, UNO_QUERY
); // order is important!
113 OSL_ENSURE(xSI
.is(), "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (must not be NULL and must have a ServiceInfo)!");
117 if (!xSI
->supportsService("com.sun.star.form.Forms"))
119 OSL_FAIL("OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (is no com.sun.star.form.Forms)!");
126 void OFormLayerXMLExport_Impl::exportGridColumn(const Reference
< XPropertySet
>& _rxColumn
,
127 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
130 OColumnExport
aExportImpl(*this, _rxColumn
, getControlId( _rxColumn
), _rEvents
);
131 aExportImpl
.doExport();
134 void OFormLayerXMLExport_Impl::exportControl(const Reference
< XPropertySet
>& _rxControl
,
135 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
137 // the list of the referring controls
138 OUString sReferringControls
;
139 MapPropertySet2String::const_iterator aReferring
= m_aCurrentPageReferring
->second
.find(_rxControl
);
140 if (aReferring
!= m_aCurrentPageReferring
->second
.end())
141 sReferringControls
= aReferring
->second
;
143 // the control id (should already have been created in examineForms)
144 OUString
sControlId( getControlId( _rxControl
) );
147 OControlExport
aExportImpl(*this, _rxControl
, sControlId
, sReferringControls
, _rEvents
);
148 aExportImpl
.doExport();
151 void OFormLayerXMLExport_Impl::exportForm(const Reference
< XPropertySet
>& _rxProps
,
152 const Sequence
< ScriptEventDescriptor
>& _rEvents
)
154 OSL_ENSURE(_rxProps
.is(), "OFormLayerXMLExport_Impl::exportForm: invalid property set!");
155 OFormExport
aAttributeHandler(*this, _rxProps
, _rEvents
);
156 aAttributeHandler
.doExport();
159 ::rtl::Reference
< SvXMLExportPropertyMapper
> OFormLayerXMLExport_Impl::getStylePropertyMapper()
161 return m_xStyleExportMapper
;
164 SvXMLExport
& OFormLayerXMLExport_Impl::getGlobalContext()
169 void OFormLayerXMLExport_Impl::exportCollectionElements(const Reference
< XIndexAccess
>& _rxCollection
)
171 // step through all the elements of the collection
172 sal_Int32 nElements
= _rxCollection
->getCount();
174 Reference
< XEventAttacherManager
> xElementEventManager(_rxCollection
, UNO_QUERY
);
175 Sequence
< ScriptEventDescriptor
> aElementEvents
;
177 Reference
< XPropertySetInfo
> xPropsInfo
;
178 for (sal_Int32 i
=0; i
<nElements
; ++i
)
182 // extract the current element
183 Reference
< XPropertySet
> xCurrentProps( _rxCollection
->getByIndex(i
), UNO_QUERY
);
184 OSL_ENSURE(xCurrentProps
.is(), "OFormLayerXMLExport_Impl::exportCollectionElements: invalid child element, skipping!");
185 if (!xCurrentProps
.is())
188 // check if there is a ClassId property on the current element. If so, we assume it to be a control
189 xPropsInfo
= xCurrentProps
->getPropertySetInfo();
190 OSL_ENSURE(xPropsInfo
.is(), "OFormLayerXMLExport_Impl::exportCollectionElements: no property set info!");
191 if (!xPropsInfo
.is())
192 // without this, a lot of stuff in the export routines may fail
195 // if the element is part of an ignore list, we are not allowed to export it
196 if ( m_aIgnoreList
.end() != m_aIgnoreList
.find( xCurrentProps
) )
199 if (xElementEventManager
.is())
200 aElementEvents
= xElementEventManager
->getScriptEvents(i
);
202 if (xPropsInfo
->hasPropertyByName(PROPERTY_COLUMNSERVICENAME
))
204 exportGridColumn(xCurrentProps
, aElementEvents
);
206 else if (xPropsInfo
->hasPropertyByName(PROPERTY_CLASSID
))
208 exportControl(xCurrentProps
, aElementEvents
);
212 exportForm(xCurrentProps
, aElementEvents
);
217 TOOLS_WARN_EXCEPTION("xmloff.forms",
218 "caught an exception ... skipping the current element!");
224 OUString
OFormLayerXMLExport_Impl::getObjectStyleName( const Reference
< XPropertySet
>& _rxObject
)
226 OUString aObjectStyle
;
228 MapPropertySet2String::const_iterator aObjectStylePos
= m_aGridColumnStyles
.find( _rxObject
);
229 if ( m_aGridColumnStyles
.end() != aObjectStylePos
)
230 aObjectStyle
= aObjectStylePos
->second
;
234 void OFormLayerXMLExport_Impl::clear()
236 m_aControlIds
.clear();
237 m_aReferringControls
.clear();
238 m_aCurrentPageIds
= m_aControlIds
.end();
239 m_aCurrentPageReferring
= m_aReferringControls
.end();
241 m_aControlNumberFormats
.clear();
242 m_aGridColumnStyles
.clear();
244 m_aIgnoreList
.clear();
247 void OFormLayerXMLExport_Impl::exportAutoControlNumberStyles()
249 if ( m_pControlNumberStyles
)
250 m_pControlNumberStyles
->Export( true );
253 void OFormLayerXMLExport_Impl::exportAutoStyles()
255 m_rContext
.GetAutoStylePool()->exportXML( XmlStyleFamily::CONTROL_ID
);
258 void OFormLayerXMLExport_Impl::exportForms(const Reference
< XDrawPage
>& _rxDrawPage
)
260 // get the forms collection of the page
261 Reference
< XIndexAccess
> xCollectionIndex
;
262 if (!impl_isFormPageContainingForms(_rxDrawPage
, xCollectionIndex
))
267 bool bPageIsKnown
= implMoveIterators(_rxDrawPage
, false);
268 OSL_ENSURE(bPageIsKnown
, "OFormLayerXMLExport_Impl::exportForms: exporting a page which has not been examined!");
270 // export forms collection
271 exportCollectionElements(xCollectionIndex
);
274 void OFormLayerXMLExport_Impl::exportXForms() const
276 // export XForms models
277 ::exportXForms( m_rContext
);
280 bool OFormLayerXMLExport_Impl::pageContainsForms( const Reference
< XDrawPage
>& _rxDrawPage
)
282 Reference
< XFormsSupplier2
> xFormsSupp( _rxDrawPage
, UNO_QUERY
);
283 SAL_WARN_IF( !xFormsSupp
.is(), "xmloff", "OFormLayerXMLExport_Impl::pageContainsForms: no XFormsSupplier2!" );
284 return xFormsSupp
.is() && xFormsSupp
->hasForms();
287 bool OFormLayerXMLExport_Impl::documentContainsXForms() const
289 Reference
< css::xforms::XFormsSupplier
> xXFormSupp( m_rContext
.GetModel(), UNO_QUERY
);
290 Reference
< XNameContainer
> xForms
;
291 if ( xXFormSupp
.is() )
292 xForms
= xXFormSupp
->getXForms();
293 return xForms
.is() && xForms
->hasElements();
296 bool OFormLayerXMLExport_Impl::implMoveIterators(const Reference
< XDrawPage
>& _rxDrawPage
, bool _bClear
)
298 if (!_rxDrawPage
.is())
301 bool bKnownPage
= false;
303 // the one for the ids
304 m_aCurrentPageIds
= m_aControlIds
.find(_rxDrawPage
);
305 if (m_aControlIds
.end() == m_aCurrentPageIds
)
307 m_aControlIds
[_rxDrawPage
] = MapPropertySet2String();
308 m_aCurrentPageIds
= m_aControlIds
.find(_rxDrawPage
);
313 if (_bClear
&& !m_aCurrentPageIds
->second
.empty() )
314 m_aCurrentPageIds
->second
.clear();
317 // the one for the ids of the referring controls
318 m_aCurrentPageReferring
= m_aReferringControls
.find(_rxDrawPage
);
319 if (m_aReferringControls
.end() == m_aCurrentPageReferring
)
321 m_aReferringControls
[_rxDrawPage
] = MapPropertySet2String();
322 m_aCurrentPageReferring
= m_aReferringControls
.find(_rxDrawPage
);
327 if (_bClear
&& !m_aCurrentPageReferring
->second
.empty() )
328 m_aCurrentPageReferring
->second
.clear();
333 bool OFormLayerXMLExport_Impl::seekPage(const Reference
< XDrawPage
>& _rxDrawPage
)
335 bool bKnownPage
= implMoveIterators( _rxDrawPage
, false );
339 // if the page is not yet known, this does not automatically mean that it has
340 // not been examined. Instead, examineForms returns silently and successfully
341 // if a page is a XFormsPageSupplier2, but does not have a forms collection
342 // (This behaviour of examineForms is a performance optimization, to not force
343 // the page to create a forms container just to see that it's empty.)
345 // So, in such a case, seekPage is considered to be successful, too, though the
346 // page was not yet known
347 Reference
< XFormsSupplier2
> xFormsSupp( _rxDrawPage
, UNO_QUERY
);
348 if ( xFormsSupp
.is() && !xFormsSupp
->hasForms() )
351 // anything else means that the page has not been examined before, or it's no
352 // valid form page. Both cases are Bad (TM).
356 OUString
OFormLayerXMLExport_Impl::getControlId(const Reference
< XPropertySet
>& _rxControl
)
358 if (m_aCurrentPageIds
== m_aControlIds
.end())
361 OSL_ENSURE(m_aCurrentPageIds
->second
.end() != m_aCurrentPageIds
->second
.find(_rxControl
),
362 "OFormLayerXMLExport_Impl::getControlId: can not find the control!");
363 return m_aCurrentPageIds
->second
[_rxControl
];
366 OUString
OFormLayerXMLExport_Impl::getImmediateNumberStyle( const Reference
< XPropertySet
>& _rxObject
)
368 OUString sNumberStyle
;
370 sal_Int32 nOwnFormatKey
= implExamineControlNumberFormat( _rxObject
);
371 if ( -1 != nOwnFormatKey
)
372 sNumberStyle
= getControlNumberStyleExport()->GetStyleName( nOwnFormatKey
);
377 OUString
OFormLayerXMLExport_Impl::getControlNumberStyle( const Reference
< XPropertySet
>& _rxControl
)
379 OUString sNumberStyle
;
381 MapPropertySet2Int::const_iterator aControlFormatPos
= m_aControlNumberFormats
.find(_rxControl
);
382 if (m_aControlNumberFormats
.end() != aControlFormatPos
)
384 OSL_ENSURE(m_pControlNumberStyles
, "OFormLayerXMLExport_Impl::getControlNumberStyle: have a control which has a format style, but no style exporter!");
385 sNumberStyle
= getControlNumberStyleExport()->GetStyleName(aControlFormatPos
->second
);
387 // it's allowed to ask for a control which does not have format information.
388 // (This is for performance reasons)
393 void OFormLayerXMLExport_Impl::examineForms(const Reference
< XDrawPage
>& _rxDrawPage
)
395 // get the forms collection of the page
396 Reference
< XIndexAccess
> xCollectionIndex
;
397 if (!impl_isFormPageContainingForms(_rxDrawPage
, xCollectionIndex
))
402 // move the iterator which specify the currently handled page
403 bool bPageIsKnown
= implMoveIterators(_rxDrawPage
, true);
404 OSL_ENSURE(!bPageIsKnown
, "OFormLayerXMLExport_Impl::examineForms: examining a page twice!");
406 ::std::stack
< Reference
< XIndexAccess
> > aContainerHistory
;
407 ::std::stack
< sal_Int32
> aIndexHistory
;
409 Reference
< XIndexAccess
> xLoop
= xCollectionIndex
;
410 sal_Int32 nChildPos
= 0;
413 if (nChildPos
< xLoop
->getCount())
415 Reference
< XPropertySet
> xCurrent( xLoop
->getByIndex( nChildPos
), UNO_QUERY
);
416 OSL_ENSURE(xCurrent
.is(), "OFormLayerXMLExport_Impl::examineForms: invalid child object");
420 if (!checkExamineControl(xCurrent
))
423 Reference
< XIndexAccess
> xNextContainer(xCurrent
, UNO_QUERY
);
424 OSL_ENSURE(xNextContainer
.is(), "OFormLayerXMLExport_Impl::examineForms: what the heck is this ... no control, no container?");
425 aContainerHistory
.push(xLoop
);
426 aIndexHistory
.push(nChildPos
);
428 xLoop
= xNextContainer
;
429 nChildPos
= -1; // will be incremented below
436 while ((nChildPos
>= xLoop
->getCount()) && !aContainerHistory
.empty() )
438 xLoop
= aContainerHistory
.top();
439 aContainerHistory
.pop();
440 nChildPos
= aIndexHistory
.top();
445 if (nChildPos
>= xLoop
->getCount())
446 // exited the loop above because we have no history anymore (0 == aContainerHistory.size()),
447 // and on the current level there are no more children
457 struct AccumulateSize
459 size_t operator()( size_t _size
, const MapPropertySet2Map::value_type
& _map
) const
461 return _size
+ _map
.second
.size();
465 OUString
lcl_findFreeControlId( const MapPropertySet2Map
& _rAllPagesControlIds
)
467 OUString sControlId
= "control";
469 size_t nKnownControlCount
= ::std::accumulate( _rAllPagesControlIds
.begin(), _rAllPagesControlIds
.end(), size_t(0), AccumulateSize() );
470 sControlId
+= OUString::number( static_cast<sal_Int32
>(nKnownControlCount
) + 1 );
473 // Check if the id is already used. It shouldn't, as we currently have no mechanism for removing entries
474 // from the map, so the approach used above (take the accumulated map size) should be sufficient. But if
475 // somebody changes this (e.g. allows removing entries from the map), the assertion below probably will fail.
476 for ( const auto& outer
: _rAllPagesControlIds
)
477 for ( const auto& inner
: outer
.second
)
479 OSL_ENSURE( inner
.second
!= sControlId
,
480 "lcl_findFreeControlId: auto-generated control ID is already used!" );
487 bool OFormLayerXMLExport_Impl::checkExamineControl(const Reference
< XPropertySet
>& _rxObject
)
489 Reference
< XPropertySetInfo
> xCurrentInfo
= _rxObject
->getPropertySetInfo();
490 OSL_ENSURE(xCurrentInfo
.is(), "OFormLayerXMLExport_Impl::checkExamineControl: no property set info");
492 bool bIsControl
= xCurrentInfo
->hasPropertyByName( PROPERTY_CLASSID
);
495 // generate a new control id
498 OUString sCurrentId
= lcl_findFreeControlId( m_aControlIds
);
500 m_aCurrentPageIds
->second
[_rxObject
] = sCurrentId
;
502 // check if this control has a "LabelControl" property referring another control
503 if ( xCurrentInfo
->hasPropertyByName( PROPERTY_CONTROLLABEL
) )
505 Reference
< XPropertySet
> xCurrentReference( _rxObject
->getPropertyValue( PROPERTY_CONTROLLABEL
), UNO_QUERY
);
506 if (xCurrentReference
.is())
508 OUString
& sReferencedBy
= m_aCurrentPageReferring
->second
[xCurrentReference
];
509 if (!sReferencedBy
.isEmpty())
510 // it's not the first _rxObject referring to the xCurrentReference
511 // -> separate the id
512 sReferencedBy
+= ",";
513 sReferencedBy
+= sCurrentId
;
517 // check if the control needs a number format style
518 if ( xCurrentInfo
->hasPropertyByName( PROPERTY_FORMATKEY
) )
520 examineControlNumberFormat(_rxObject
);
523 // check if it's a control providing text
524 Reference
< XText
> xControlText( _rxObject
, UNO_QUERY
);
525 if ( xControlText
.is() )
527 m_rContext
.GetTextParagraphExport()->collectTextAutoStyles( xControlText
);
530 // check if it is a grid control - in this case, we need special handling for the columns
531 sal_Int16 nControlType
= FormComponentType::CONTROL
;
532 _rxObject
->getPropertyValue( PROPERTY_CLASSID
) >>= nControlType
;
533 if ( FormComponentType::GRIDCONTROL
== nControlType
)
535 collectGridColumnStylesAndIds( _rxObject
);
542 void OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds( const Reference
< XPropertySet
>& _rxControl
)
544 // loop through all columns of the grid
547 Reference
< XIndexAccess
> xContainer( _rxControl
, UNO_QUERY
);
548 OSL_ENSURE( xContainer
.is(), "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: grid control not being a container?!" );
549 if ( !xContainer
.is() )
552 Reference
< XPropertySetInfo
> xColumnPropertiesMeta
;
554 sal_Int32 nCount
= xContainer
->getCount();
555 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
557 Reference
< XPropertySet
> xColumnProperties( xContainer
->getByIndex( i
), UNO_QUERY
);
558 OSL_ENSURE( xColumnProperties
.is(), "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: invalid grid column encountered!" );
559 if ( !xColumnProperties
.is() )
562 // generate a new control id
565 OUString sCurrentId
= lcl_findFreeControlId( m_aControlIds
);
567 m_aCurrentPageIds
->second
[ xColumnProperties
] = sCurrentId
;
569 // determine a number style, if needed
570 xColumnPropertiesMeta
= xColumnProperties
->getPropertySetInfo();
571 // get the styles of the column
572 ::std::vector
<XMLPropertyState
> aPropertyStates
= m_xStyleExportMapper
->Filter(m_rContext
, xColumnProperties
);
574 // care for the number format, additionally
575 OUString sColumnNumberStyle
;
576 if ( xColumnPropertiesMeta
.is() && xColumnPropertiesMeta
->hasPropertyByName( PROPERTY_FORMATKEY
) )
577 sColumnNumberStyle
= getImmediateNumberStyle( xColumnProperties
);
579 if ( !sColumnNumberStyle
.isEmpty() )
580 { // the column indeed has a formatting
581 sal_Int32 nStyleMapIndex
= m_xStyleExportMapper
->getPropertySetMapper()->FindEntryIndex( CTF_FORMS_DATA_STYLE
);
582 // TODO: move this to the ctor
583 OSL_ENSURE ( -1 != nStyleMapIndex
, "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: could not obtain the index for our context id!");
585 XMLPropertyState
aNumberStyleState( nStyleMapIndex
, Any( sColumnNumberStyle
) );
586 aPropertyStates
.push_back( aNumberStyleState
);
589 // determine the column style
591 if ( !aPropertyStates
.empty() )
592 { // add to the style pool
593 OUString sColumnStyleName
= m_rContext
.GetAutoStylePool()->Add( XmlStyleFamily::CONTROL_ID
, std::move(aPropertyStates
) );
595 OSL_ENSURE( m_aGridColumnStyles
.end() == m_aGridColumnStyles
.find( xColumnProperties
),
596 "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: already have a style for this column!" );
598 m_aGridColumnStyles
.emplace( xColumnProperties
, sColumnStyleName
);
602 catch( const Exception
& )
604 DBG_UNHANDLED_EXCEPTION("xmloff.forms");
608 sal_Int32
OFormLayerXMLExport_Impl::implExamineControlNumberFormat( const Reference
< XPropertySet
>& _rxObject
)
610 // get the format key relative to our own formats supplier
611 sal_Int32 nOwnFormatKey
= ensureTranslateFormat( _rxObject
);
613 if ( -1 != nOwnFormatKey
)
614 // tell the exporter that we used this format
615 getControlNumberStyleExport()->SetUsed( nOwnFormatKey
);
617 return nOwnFormatKey
;
620 void OFormLayerXMLExport_Impl::examineControlNumberFormat( const Reference
< XPropertySet
>& _rxControl
)
622 sal_Int32 nOwnFormatKey
= implExamineControlNumberFormat( _rxControl
);
624 if ( -1 == nOwnFormatKey
)
625 // nothing to do, the number format of this control is void
628 // remember the format key for this control (we'll be asked in getControlNumberStyle for this)
629 OSL_ENSURE(m_aControlNumberFormats
.end() == m_aControlNumberFormats
.find(_rxControl
),
630 "OFormLayerXMLExport_Impl::examineControlNumberFormat: already handled this control!");
631 m_aControlNumberFormats
[_rxControl
] = nOwnFormatKey
;
634 sal_Int32
OFormLayerXMLExport_Impl::ensureTranslateFormat(const Reference
< XPropertySet
>& _rxFormattedControl
)
636 ensureControlNumberStyleExport();
637 OSL_ENSURE(m_xControlNumberFormats
.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: no own formats supplier!");
638 // (should have been created in ensureControlNumberStyleExport)
640 sal_Int32 nOwnFormatKey
= -1;
642 // the format key (relative to the control's supplier)
643 sal_Int32 nControlFormatKey
= -1;
644 Any aControlFormatKey
= _rxFormattedControl
->getPropertyValue(PROPERTY_FORMATKEY
);
645 if (aControlFormatKey
>>= nControlFormatKey
)
647 // the control's number format
648 Reference
< XNumberFormatsSupplier
> xControlFormatsSupplier
;
649 _rxFormattedControl
->getPropertyValue(PROPERTY_FORMATSSUPPLIER
) >>= xControlFormatsSupplier
;
650 Reference
< XNumberFormats
> xControlFormats
;
651 if (xControlFormatsSupplier
.is())
652 xControlFormats
= xControlFormatsSupplier
->getNumberFormats();
653 OSL_ENSURE(xControlFormats
.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: formatted control without supplier!");
655 // obtain the persistent (does not depend on the formats supplier) representation of the control's format
656 Locale aFormatLocale
;
657 OUString sFormatDescription
;
658 if (xControlFormats
.is())
660 Reference
< XPropertySet
> xControlFormat
= xControlFormats
->getByKey(nControlFormatKey
);
662 xControlFormat
->getPropertyValue(PROPERTY_LOCALE
) >>= aFormatLocale
;
663 xControlFormat
->getPropertyValue(PROPERTY_FORMATSTRING
) >>= sFormatDescription
;
666 // check if our own formats collection already knows the format
667 nOwnFormatKey
= m_xControlNumberFormats
->queryKey(sFormatDescription
, aFormatLocale
, false);
668 if (-1 == nOwnFormatKey
)
670 // -> create a new format
671 nOwnFormatKey
= m_xControlNumberFormats
->addNew(sFormatDescription
, aFormatLocale
);
673 OSL_ENSURE(-1 != nOwnFormatKey
, "OFormLayerXMLExport_Impl::ensureTranslateFormat: could not translate the controls format key!");
676 OSL_ENSURE(!aControlFormatKey
.hasValue(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: invalid number format property value!");
678 return nOwnFormatKey
;
681 void OFormLayerXMLExport_Impl::ensureControlNumberStyleExport()
683 if (m_pControlNumberStyles
)
686 // create our number formats supplier (if necessary)
687 Reference
< XNumberFormatsSupplier
> xFormatsSupplier
;
689 OSL_ENSURE(!m_xControlNumberFormats
.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: inconsistence!");
690 // the m_xControlNumberFormats and m_pControlNumberStyles should be maintained together
694 // create it for en-US (does not really matter, as we will specify a locale for every
695 // concrete language to use)
696 Locale
aLocale ( "en", "US", OUString() );
697 xFormatsSupplier
= NumberFormatsSupplier::createWithLocale( m_rContext
.getComponentContext(), aLocale
);
698 m_xControlNumberFormats
= xFormatsSupplier
->getNumberFormats();
700 catch(const Exception
&)
704 OSL_ENSURE(m_xControlNumberFormats
.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: could not obtain my default number formats!");
706 // create the exporter
707 m_pControlNumberStyles
= new SvXMLNumFmtExport(m_rContext
, xFormatsSupplier
, getControlNumberStyleNamePrefix());
710 SvXMLNumFmtExport
* OFormLayerXMLExport_Impl::getControlNumberStyleExport()
712 ensureControlNumberStyleExport();
713 return m_pControlNumberStyles
;
716 void OFormLayerXMLExport_Impl::excludeFromExport( const Reference
< XControlModel
>& _rxControl
)
718 Reference
< XPropertySet
> xProps( _rxControl
, UNO_QUERY
);
719 OSL_ENSURE( xProps
.is(), "OFormLayerXMLExport_Impl::excludeFromExport: invalid control model!" );
720 ::std::pair
< PropertySetBag::const_iterator
, bool > aPos
=
721 m_aIgnoreList
.insert( xProps
);
722 OSL_ENSURE( aPos
.second
, "OFormLayerXMLExport_Impl::excludeFromExport: element already exists in the ignore list!" );
725 } // namespace xmloff
727 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */