bump product version to 7.6.3.2-android
[LibreOffice.git] / xmloff / source / forms / layerexport.cxx
blobd1e92bca920d39aef4935fc897c7e6c2e8373ad6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
48 #include <stack>
49 #include <numeric>
51 namespace xmloff
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 );
83 // our style family
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);
93 clear();
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())
105 return false;
107 if ( !xFormsSupp->hasForms() )
108 // nothing to do at all
109 return false;
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)!");
114 if (!xSI.is())
115 return false;
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)!");
120 // nothing to do
121 return false;
123 return true;
126 void OFormLayerXMLExport_Impl::exportGridColumn(const Reference< XPropertySet >& _rxColumn,
127 const Sequence< ScriptEventDescriptor >& _rEvents)
129 // do the exporting
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 ) );
146 // do the exporting
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()
166 return m_rContext;
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())
186 continue;
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
193 continue;
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 ) )
197 continue;
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);
210 else
212 exportForm(xCurrentProps, aElementEvents);
215 catch(Exception&)
217 TOOLS_WARN_EXCEPTION("xmloff.forms",
218 "caught an exception ... skipping the current element!");
219 continue;
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;
231 return aObjectStyle;
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))
264 return;
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())
299 return false;
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);
310 else
312 bKnownPage = true;
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);
324 else
326 bKnownPage = true;
327 if (_bClear && !m_aCurrentPageReferring->second.empty() )
328 m_aCurrentPageReferring->second.clear();
330 return bKnownPage;
333 bool OFormLayerXMLExport_Impl::seekPage(const Reference< XDrawPage >& _rxDrawPage)
335 bool bKnownPage = implMoveIterators( _rxDrawPage, false );
336 if ( bKnownPage )
337 return true;
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() )
349 return true;
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).
353 return false;
356 OUString OFormLayerXMLExport_Impl::getControlId(const Reference< XPropertySet >& _rxControl)
358 if (m_aCurrentPageIds == m_aControlIds.end())
359 return OUString();
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 );
374 return sNumberStyle;
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)
390 return sNumberStyle;
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))
399 return;
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");
417 if (!xCurrent.is())
418 continue;
420 if (!checkExamineControl(xCurrent))
422 // step down
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
431 ++nChildPos;
433 else
435 // step up
436 while ((nChildPos >= xLoop->getCount()) && !aContainerHistory.empty() )
438 xLoop = aContainerHistory.top();
439 aContainerHistory.pop();
440 nChildPos = aIndexHistory.top();
441 aIndexHistory.pop();
443 ++nChildPos;
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
448 // -> leave
449 break;
452 while (xLoop.is());
455 namespace
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 );
472 #ifdef DBG_UTIL
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!" );
482 #endif
483 return sControlId;
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 );
493 if (bIsControl)
495 // generate a new control id
497 // find a free id
498 OUString sCurrentId = lcl_findFreeControlId( m_aControlIds );
499 // add it to the map
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 );
539 return bIsControl;
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() )
550 return;
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() )
560 continue;
562 // generate a new control id
564 // find a free id
565 OUString sCurrentId = lcl_findFreeControlId( m_aControlIds );
566 // add it to the map
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
626 return;
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)
669 { // no, we don't
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!");
675 else
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)
684 return;
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: */