LibreOffice Module xmloff (master) 1
layerexport.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
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>
29#include <xmloff/maptype.hxx>
30#include <sal/log.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>
42#include "formevents.hxx"
43#include <xmloff/xmlnumfe.hxx>
45
46#include <com/sun/star/text/XText.hpp>
47
48#include <stack>
49#include <numeric>
50
51namespace xmloff
52{
53
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;
64
65 //= OFormLayerXMLExport_Impl
67 {
68 static const OUString s_sControlNumberStyleNamePrefix("C");
69 return s_sControlNumberStyleNamePrefix;
70 }
71
73 :m_rContext(_rContext)
74 ,m_pControlNumberStyles(nullptr)
75 {
77
78 // add our style family to the export context's style pool
81 m_xStyleExportMapper = new OFormComponentStyleExportMapper( xStylePropertiesMapper );
82
83 // our style family
84 m_rContext.GetAutoStylePool()->AddFamily(
88 );
89
90 // add our event translation table
92
93 clear();
94 }
95
97 {
98 }
99
100 bool OFormLayerXMLExport_Impl::impl_isFormPageContainingForms(const Reference< XDrawPage >& _rxDrawPage, Reference< XIndexAccess >& _rxForms)
101 {
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;
106
107 if ( !xFormsSupp->hasForms() )
108 // nothing to do at all
109 return false;
110
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;
116
117 if (!xSI->supportsService("com.sun.star.form.Forms"))
118 {
119 OSL_FAIL("OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (is no com.sun.star.form.Forms)!");
120 // nothing to do
121 return false;
122 }
123 return true;
124 }
125
126 void OFormLayerXMLExport_Impl::exportGridColumn(const Reference< XPropertySet >& _rxColumn,
127 const Sequence< ScriptEventDescriptor >& _rEvents)
128 {
129 // do the exporting
130 OColumnExport aExportImpl(*this, _rxColumn, getControlId( _rxColumn ), _rEvents);
131 aExportImpl.doExport();
132 }
133
134 void OFormLayerXMLExport_Impl::exportControl(const Reference< XPropertySet >& _rxControl,
135 const Sequence< ScriptEventDescriptor >& _rEvents)
136 {
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;
142
143 // the control id (should already have been created in examineForms)
144 OUString sControlId( getControlId( _rxControl ) );
145
146 // do the exporting
147 OControlExport aExportImpl(*this, _rxControl, sControlId, sReferringControls, _rEvents);
148 aExportImpl.doExport();
149 }
150
151 void OFormLayerXMLExport_Impl::exportForm(const Reference< XPropertySet >& _rxProps,
152 const Sequence< ScriptEventDescriptor >& _rEvents)
153 {
154 OSL_ENSURE(_rxProps.is(), "OFormLayerXMLExport_Impl::exportForm: invalid property set!");
155 OFormExport aAttributeHandler(*this, _rxProps, _rEvents);
156 aAttributeHandler.doExport();
157 }
158
160 {
162 }
163
165 {
166 return m_rContext;
167 }
168
169 void OFormLayerXMLExport_Impl::exportCollectionElements(const Reference< XIndexAccess >& _rxCollection)
170 {
171 // step through all the elements of the collection
172 sal_Int32 nElements = _rxCollection->getCount();
173
174 Reference< XEventAttacherManager > xElementEventManager(_rxCollection, UNO_QUERY);
175 Sequence< ScriptEventDescriptor > aElementEvents;
176
177 Reference< XPropertySetInfo > xPropsInfo;
178 for (sal_Int32 i=0; i<nElements; ++i)
179 {
180 try
181 {
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;
187
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;
194
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;
198
199 if (xElementEventManager.is())
200 aElementEvents = xElementEventManager->getScriptEvents(i);
201
202 if (xPropsInfo->hasPropertyByName(PROPERTY_COLUMNSERVICENAME))
203 {
204 exportGridColumn(xCurrentProps, aElementEvents);
205 }
206 else if (xPropsInfo->hasPropertyByName(PROPERTY_CLASSID))
207 {
208 exportControl(xCurrentProps, aElementEvents);
209 }
210 else
211 {
212 exportForm(xCurrentProps, aElementEvents);
213 }
214 }
215 catch(Exception&)
216 {
217 TOOLS_WARN_EXCEPTION("xmloff.forms",
218 "caught an exception ... skipping the current element!");
219 continue;
220 }
221 }
222 }
223
224 OUString OFormLayerXMLExport_Impl::getObjectStyleName( const Reference< XPropertySet >& _rxObject )
225 {
226 OUString aObjectStyle;
227
228 MapPropertySet2String::const_iterator aObjectStylePos = m_aGridColumnStyles.find( _rxObject );
229 if ( m_aGridColumnStyles.end() != aObjectStylePos )
230 aObjectStyle = aObjectStylePos->second;
231 return aObjectStyle;
232 }
233
235 {
236 m_aControlIds.clear();
237 m_aReferringControls.clear();
240
242 m_aGridColumnStyles.clear();
243
245 }
246
248 {
251 }
252
254 {
256 }
257
258 void OFormLayerXMLExport_Impl::exportForms(const Reference< XDrawPage >& _rxDrawPage)
259 {
260 // get the forms collection of the page
261 Reference< XIndexAccess > xCollectionIndex;
262 if (!impl_isFormPageContainingForms(_rxDrawPage, xCollectionIndex))
263 {
264 return;
265 }
266
267 bool bPageIsKnown = implMoveIterators(_rxDrawPage, false);
268 OSL_ENSURE(bPageIsKnown, "OFormLayerXMLExport_Impl::exportForms: exporting a page which has not been examined!");
269
270 // export forms collection
271 exportCollectionElements(xCollectionIndex);
272 }
273
275 {
276 // export XForms models
278 }
279
280 bool OFormLayerXMLExport_Impl::pageContainsForms( const Reference< XDrawPage >& _rxDrawPage )
281 {
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();
285 }
286
288 {
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();
294 }
295
296 bool OFormLayerXMLExport_Impl::implMoveIterators(const Reference< XDrawPage >& _rxDrawPage, bool _bClear)
297 {
298 if (!_rxDrawPage.is())
299 return false;
300
301 bool bKnownPage = false;
302
303 // the one for the ids
304 m_aCurrentPageIds = m_aControlIds.find(_rxDrawPage);
305 if (m_aControlIds.end() == m_aCurrentPageIds)
306 {
307 m_aControlIds[_rxDrawPage] = MapPropertySet2String();
308 m_aCurrentPageIds = m_aControlIds.find(_rxDrawPage);
309 }
310 else
311 {
312 bKnownPage = true;
313 if (_bClear && !m_aCurrentPageIds->second.empty() )
314 m_aCurrentPageIds->second.clear();
315 }
316
317 // the one for the ids of the referring controls
320 {
323 }
324 else
325 {
326 bKnownPage = true;
327 if (_bClear && !m_aCurrentPageReferring->second.empty() )
328 m_aCurrentPageReferring->second.clear();
329 }
330 return bKnownPage;
331 }
332
333 bool OFormLayerXMLExport_Impl::seekPage(const Reference< XDrawPage >& _rxDrawPage)
334 {
335 bool bKnownPage = implMoveIterators( _rxDrawPage, false );
336 if ( bKnownPage )
337 return true;
338
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.)
344
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;
350
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;
354 }
355
356 OUString OFormLayerXMLExport_Impl::getControlId(const Reference< XPropertySet >& _rxControl)
357 {
358 if (m_aCurrentPageIds == m_aControlIds.end())
359 return OUString();
360
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];
364 }
365
366 OUString OFormLayerXMLExport_Impl::getImmediateNumberStyle( const Reference< XPropertySet >& _rxObject )
367 {
368 OUString sNumberStyle;
369
370 sal_Int32 nOwnFormatKey = implExamineControlNumberFormat( _rxObject );
371 if ( -1 != nOwnFormatKey )
372 sNumberStyle = getControlNumberStyleExport()->GetStyleName( nOwnFormatKey );
373
374 return sNumberStyle;
375 }
376
377 OUString OFormLayerXMLExport_Impl::getControlNumberStyle( const Reference< XPropertySet >& _rxControl )
378 {
379 OUString sNumberStyle;
380
381 MapPropertySet2Int::const_iterator aControlFormatPos = m_aControlNumberFormats.find(_rxControl);
382 if (m_aControlNumberFormats.end() != aControlFormatPos)
383 {
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);
386 }
387 // it's allowed to ask for a control which does not have format information.
388 // (This is for performance reasons)
389
390 return sNumberStyle;
391 }
392
393 void OFormLayerXMLExport_Impl::examineForms(const Reference< XDrawPage >& _rxDrawPage)
394 {
395 // get the forms collection of the page
396 Reference< XIndexAccess > xCollectionIndex;
397 if (!impl_isFormPageContainingForms(_rxDrawPage, xCollectionIndex))
398 {
399 return;
400 }
401
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!");
405
406 ::std::stack< Reference< XIndexAccess > > aContainerHistory;
407 ::std::stack< sal_Int32 > aIndexHistory;
408
409 Reference< XIndexAccess > xLoop = xCollectionIndex;
410 sal_Int32 nChildPos = 0;
411 do
412 {
413 if (nChildPos < xLoop->getCount())
414 {
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;
419
420 if (!checkExamineControl(xCurrent))
421 {
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);
427
428 xLoop = xNextContainer;
429 nChildPos = -1; // will be incremented below
430 }
431 ++nChildPos;
432 }
433 else
434 {
435 // step up
436 while ((nChildPos >= xLoop->getCount()) && !aContainerHistory.empty() )
437 {
438 xLoop = aContainerHistory.top();
439 aContainerHistory.pop();
440 nChildPos = aIndexHistory.top();
441 aIndexHistory.pop();
442
443 ++nChildPos;
444 }
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;
450 }
451 }
452 while (xLoop.is());
453 }
454
455 namespace
456 {
457 struct AccumulateSize
458 {
459 size_t operator()( size_t _size, const MapPropertySet2Map::value_type& _map ) const
460 {
461 return _size + _map.second.size();
462 }
463 };
464
465 OUString lcl_findFreeControlId( const MapPropertySet2Map& _rAllPagesControlIds )
466 {
467 OUString sControlId = "control";
468
469 size_t nKnownControlCount = ::std::accumulate( _rAllPagesControlIds.begin(), _rAllPagesControlIds.end(), size_t(0), AccumulateSize() );
470 sControlId += OUString::number( static_cast<sal_Int32>(nKnownControlCount) + 1 );
471
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 )
478 {
479 OSL_ENSURE( inner.second != sControlId,
480 "lcl_findFreeControlId: auto-generated control ID is already used!" );
481 }
482 #endif
483 return sControlId;
484 }
485 }
486
487 bool OFormLayerXMLExport_Impl::checkExamineControl(const Reference< XPropertySet >& _rxObject)
488 {
489 Reference< XPropertySetInfo > xCurrentInfo = _rxObject->getPropertySetInfo();
490 OSL_ENSURE(xCurrentInfo.is(), "OFormLayerXMLExport_Impl::checkExamineControl: no property set info");
491
492 bool bIsControl = xCurrentInfo->hasPropertyByName( PROPERTY_CLASSID );
493 if (bIsControl)
494 {
495 // generate a new control id
496
497 // find a free id
498 OUString sCurrentId = lcl_findFreeControlId( m_aControlIds );
499 // add it to the map
500 m_aCurrentPageIds->second[_rxObject] = sCurrentId;
501
502 // check if this control has a "LabelControl" property referring another control
503 if ( xCurrentInfo->hasPropertyByName( PROPERTY_CONTROLLABEL ) )
504 {
505 Reference< XPropertySet > xCurrentReference( _rxObject->getPropertyValue( PROPERTY_CONTROLLABEL ), UNO_QUERY );
506 if (xCurrentReference.is())
507 {
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;
514 }
515 }
516
517 // check if the control needs a number format style
518 if ( xCurrentInfo->hasPropertyByName( PROPERTY_FORMATKEY ) )
519 {
521 }
522
523 // check if it's a control providing text
524 Reference< XText > xControlText( _rxObject, UNO_QUERY );
525 if ( xControlText.is() )
526 {
527 m_rContext.GetTextParagraphExport()->collectTextAutoStyles( xControlText );
528 }
529
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 )
534 {
536 }
537 }
538
539 return bIsControl;
540 }
541
542 void OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds( const Reference< XPropertySet >& _rxControl )
543 {
544 // loop through all columns of the grid
545 try
546 {
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;
551
552 Reference< XPropertySetInfo > xColumnPropertiesMeta;
553
554 sal_Int32 nCount = xContainer->getCount();
555 for ( sal_Int32 i=0; i<nCount; ++i )
556 {
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;
561
562 // generate a new control id
563
564 // find a free id
565 OUString sCurrentId = lcl_findFreeControlId( m_aControlIds );
566 // add it to the map
567 m_aCurrentPageIds->second[ xColumnProperties ] = sCurrentId;
568
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);
573
574 // care for the number format, additionally
575 OUString sColumnNumberStyle;
576 if ( xColumnPropertiesMeta.is() && xColumnPropertiesMeta->hasPropertyByName( PROPERTY_FORMATKEY ) )
577 sColumnNumberStyle = getImmediateNumberStyle( xColumnProperties );
578
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!");
584
585 XMLPropertyState aNumberStyleState( nStyleMapIndex, Any( sColumnNumberStyle ) );
586 aPropertyStates.push_back( aNumberStyleState );
587 }
588
589 // determine the column style
590
591 if ( !aPropertyStates.empty() )
592 { // add to the style pool
593 OUString sColumnStyleName = m_rContext.GetAutoStylePool()->Add( XmlStyleFamily::CONTROL_ID, std::move(aPropertyStates) );
594
595 OSL_ENSURE( m_aGridColumnStyles.end() == m_aGridColumnStyles.find( xColumnProperties ),
596 "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: already have a style for this column!" );
597
598 m_aGridColumnStyles.emplace( xColumnProperties, sColumnStyleName );
599 }
600 }
601 }
602 catch( const Exception& )
603 {
604 DBG_UNHANDLED_EXCEPTION("xmloff.forms");
605 }
606 }
607
608 sal_Int32 OFormLayerXMLExport_Impl::implExamineControlNumberFormat( const Reference< XPropertySet >& _rxObject )
609 {
610 // get the format key relative to our own formats supplier
611 sal_Int32 nOwnFormatKey = ensureTranslateFormat( _rxObject );
612
613 if ( -1 != nOwnFormatKey )
614 // tell the exporter that we used this format
615 getControlNumberStyleExport()->SetUsed( nOwnFormatKey );
616
617 return nOwnFormatKey;
618 }
619
620 void OFormLayerXMLExport_Impl::examineControlNumberFormat( const Reference< XPropertySet >& _rxControl )
621 {
622 sal_Int32 nOwnFormatKey = implExamineControlNumberFormat( _rxControl );
623
624 if ( -1 == nOwnFormatKey )
625 // nothing to do, the number format of this control is void
626 return;
627
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;
632 }
633
634 sal_Int32 OFormLayerXMLExport_Impl::ensureTranslateFormat(const Reference< XPropertySet >& _rxFormattedControl)
635 {
637 OSL_ENSURE(m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: no own formats supplier!");
638 // (should have been created in ensureControlNumberStyleExport)
639
640 sal_Int32 nOwnFormatKey = -1;
641
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)
646 {
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!");
654
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())
659 {
660 Reference< XPropertySet > xControlFormat = xControlFormats->getByKey(nControlFormatKey);
661
662 xControlFormat->getPropertyValue(PROPERTY_LOCALE) >>= aFormatLocale;
663 xControlFormat->getPropertyValue(PROPERTY_FORMATSTRING) >>= sFormatDescription;
664 }
665
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);
672 }
673 OSL_ENSURE(-1 != nOwnFormatKey, "OFormLayerXMLExport_Impl::ensureTranslateFormat: could not translate the controls format key!");
674 }
675 else
676 OSL_ENSURE(!aControlFormatKey.hasValue(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: invalid number format property value!");
677
678 return nOwnFormatKey;
679 }
680
682 {
684 return;
685
686 // create our number formats supplier (if necessary)
687 Reference< XNumberFormatsSupplier > xFormatsSupplier;
688
689 OSL_ENSURE(!m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: inconsistence!");
690 // the m_xControlNumberFormats and m_pControlNumberStyles should be maintained together
691
692 try
693 {
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();
699 }
700 catch(const Exception&)
701 {
702 }
703
704 OSL_ENSURE(m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: could not obtain my default number formats!");
705
706 // create the exporter
708 }
709
711 {
714 }
715
716 void OFormLayerXMLExport_Impl::excludeFromExport( const Reference< XControlModel >& _rxControl )
717 {
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!" );
723 }
724
725} // namespace xmloff
726
727/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XMLEventExport & GetEventExport()
get Event export, with handlers for script types "None" and "StarBasic" already registered; other han...
Definition: xmlexp.cxx:1989
rtl::Reference< XMLTextParagraphExport > const & GetTextParagraphExport()
Definition: xmlexp.hxx:557
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlexp.hxx:411
rtl::Reference< SvXMLAutoStylePoolP > const & GetAutoStylePool()
Definition: xmlexp.hxx:573
const css::uno::Reference< css::uno::XComponentContext > & getComponentContext() const
Definition: xmlexp.hxx:517
OUString GetStyleName(sal_uInt32 nKey)
Definition: xmlnumfe.cxx:1962
void Export(bool bIsAutoStyle)
Definition: xmlnumfe.cxx:1911
void SetUsed(sal_uInt32 nKey)
Definition: xmlnumfe.cxx:1973
void AddTranslationTable(const XMLEventNameTranslation *pTransTable)
register additional event names
const_iterator find(const Value &x) const
const_iterator end() const
std::pair< const_iterator, bool > insert(Value &&x)
Helper class for exporting a grid column.
Helper class for handling xml elements representing a form control.
Helper class for handling xml elements representing a form.
virtual SvXMLExport & getGlobalContext() override
bool documentContainsXForms() const
determines whether the given page contains XForm instances
OUString getControlId(const css::uno::Reference< css::beans::XPropertySet > &_rxControl)
get the id of the given control.
virtual OUString getObjectStyleName(const css::uno::Reference< css::beans::XPropertySet > &_rxObject) override
sal_Int32 implExamineControlNumberFormat(const css::uno::Reference< css::beans::XPropertySet > &_rxObject)
examines the control's number format, so later the format style can be referred
void exportControl(const css::uno::Reference< css::beans::XPropertySet > &_rxControl, const css::uno::Sequence< css::script::ScriptEventDescriptor > &_rEvents)
exports one single control
OUString getControlNumberStyle(const css::uno::Reference< css::beans::XPropertySet > &_rxControl)
retrieves the style name for the control's number style.
void examineControlNumberFormat(const css::uno::Reference< css::beans::XPropertySet > &_rxControl)
examines the control's number format, so later the format style can be referred
sal_Int32 ensureTranslateFormat(const css::uno::Reference< css::beans::XPropertySet > &_rxFormattedControl)
ensures that the number format of the given control exist in our own formats supplier.
MapPropertySet2Map::iterator m_aCurrentPageIds
void ensureControlNumberStyleExport()
ensures that the instance exporting our control's number styles exists
bool checkExamineControl(const css::uno::Reference< css::beans::XPropertySet > &_rxObject)
check the object given if it's a control, if so, examine it.
void exportForm(const css::uno::Reference< css::beans::XPropertySet > &_rxProps, const css::uno::Sequence< css::script::ScriptEventDescriptor > &_rEvents)
exports one single form
static const OUString & getControlNumberStyleNamePrefix()
returns the prefix to be used for control number styles
Definition: layerexport.cxx:66
SvXMLNumFmtExport * getControlNumberStyleExport()
returns the instance exporting our control's number styles
void exportAutoStyles()
exports the auto-styles collected during the examineForms calls
MapPropertySet2String m_aGridColumnStyles
OFormLayerXMLExport_Impl(SvXMLExport &_rContext)
Definition: layerexport.cxx:72
::rtl::Reference< SvXMLExportPropertyMapper > m_xStyleExportMapper
Definition: layerexport.hxx:71
MapPropertySet2Int m_aControlNumberFormats
SvXMLNumFmtExport * m_pControlNumberStyles
Definition: layerexport.hxx:64
void exportGridColumn(const css::uno::Reference< css::beans::XPropertySet > &_rxColumn, const css::uno::Sequence< css::script::ScriptEventDescriptor > &_rEvents)
exports one single grid column
css::uno::Reference< css::util::XNumberFormats > m_xControlNumberFormats
Definition: layerexport.hxx:90
void exportAutoControlNumberStyles()
exports the automatic control number styles
virtual void exportCollectionElements(const css::uno::Reference< css::container::XIndexAccess > &_rxCollection) override
steps through a collection and exports all children of this collection
virtual ::rtl::Reference< SvXMLExportPropertyMapper > getStylePropertyMapper() override
MapPropertySet2Map m_aControlIds
Definition: layerexport.hxx:92
void clear()
clear any structures which have been build in the recent <method>examine</method> calls.
MapPropertySet2Map m_aReferringControls
Definition: layerexport.hxx:95
MapPropertySet2Map::iterator m_aCurrentPageReferring
::rtl::Reference< XMLPropertyHandlerFactory > m_xPropertyHandlerFactory
Definition: layerexport.hxx:70
void excludeFromExport(const css::uno::Reference< css::awt::XControlModel > &_rxControl)
exclude the given control (model) from export.
static bool pageContainsForms(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage)
determines whether the given page contains logical forms
OUString getImmediateNumberStyle(const css::uno::Reference< css::beans::XPropertySet > &_rxObject)
determines the number format style for the given object without remembering it
bool seekPage(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage)
seek to the page given.
void collectGridColumnStylesAndIds(const css::uno::Reference< css::beans::XPropertySet > &_rxControl)
collects AutoStyles for grid columns
bool implMoveIterators(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage, bool _bClear)
moves the m_aCurrentPage* members to the positions specifying the given page.
void examineForms(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage)
examine a forms collection.
static bool impl_isFormPageContainingForms(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage, css::uno::Reference< css::container::XIndexAccess > &_rxForms)
void exportForms(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage)
export a forms collection of a draw page
void exportXForms() const
exports the XForms model data
#define CTF_FORMS_DATA_STYLE
Definition: contextid.hxx:39
sal_Int32 nElements
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
constexpr OUStringLiteral XML_STYLE_FAMILY_CONTROL_PREFIX
Definition: families.hxx:47
#define SAL_WARN_IF(condition, area, stream)
@ Exception
void * _map(void *p, typelib_TypeDescriptionReference *pType, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping)
int i
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3541
constexpr OUStringLiteral PROPERTY_COLUMNSERVICENAME
Definition: strings.hxx:106
::std::unordered_map< css::uno::Reference< css::drawing::XDrawPage >, MapPropertySet2String > MapPropertySet2Map
Definition: layerexport.hxx:53
void initializePropertyMaps()
constexpr OUStringLiteral PROPERTY_CLASSID
Definition: strings.hxx:28
const XMLEventNameTranslation * g_pFormsEventTranslation
Definition: formevents.cxx:66
::std::unordered_map< css::uno::Reference< css::beans::XPropertySet >, OUString > MapPropertySet2String
Definition: layerexport.hxx:48
constexpr OUStringLiteral PROPERTY_CONTROLLABEL
Definition: strings.hxx:76
constexpr OUStringLiteral PROPERTY_FORMATSTRING
Definition: strings.hxx:114
const XMLPropertyMapEntry * getControlStylePropertyMap()
constexpr OUStringLiteral PROPERTY_LOCALE
Definition: strings.hxx:113
constexpr OUStringLiteral PROPERTY_FORMATSSUPPLIER
Definition: strings.hxx:112
constexpr OUStringLiteral PROPERTY_FORMATKEY
Definition: strings.hxx:107
Smart struct to transport an Any with an index to the appropriate property-name.
Definition: maptype.hxx:140
const Reference< XComponentContext > & m_rContext