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>
31 #include <tools/diagnose_ex.h>
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>
42 #include "formevents.hxx"
43 #include <xmloff/xmlnumfe.hxx>
44 #include <xmloff/xformsexport.hxx>
45 
46 #include <com/sun/star/text/XText.hpp>
47 
48 #include <stack>
49 #include <numeric>
50 
51 namespace 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.get() );
82 
83  // our style family
84  m_rContext.GetAutoStylePool()->AddFamily(
86  m_xStyleExportMapper.get(),
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 
127  const Sequence< ScriptEventDescriptor >& _rEvents)
128  {
129  // do the exporting
130  OColumnExport aExportImpl(*this, _rxColumn, getControlId( _rxColumn ), _rEvents);
131  aExportImpl.doExport();
132  }
133 
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 
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  {
161  return m_xStyleExportMapper;
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 
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 
241  m_aControlNumberFormats.clear();
242  m_aGridColumnStyles.clear();
243 
244  m_aIgnoreList.clear();
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
318  m_aCurrentPageReferring = m_aReferringControls.find(_rxDrawPage);
320  {
322  m_aCurrentPageReferring = m_aReferringControls.find(_rxDrawPage);
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 
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 
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 
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 
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  {
520  examineControlNumberFormat(_rxObject);
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  {
535  collectGridColumnStylesAndIds( _rxObject );
536  }
537  }
538 
539  return bIsControl;
540  }
541 
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( 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, makeAny( 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, 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 
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 
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 
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  {
713  return m_pControlNumberStyles;
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::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: */
css::uno::Reference< css::util::XNumberFormats > m_xControlNumberFormats
Definition: layerexport.hxx:92
bool documentContainsXForms() const
determines whether the given page contains XForm instances
void exportXForms() const
exports the XForms model data
void excludeFromExport(const css::uno::Reference< css::awt::XControlModel > &_rxControl)
exclude the given control (model) from export.
void AddTranslationTable(const XMLEventNameTranslation *pTransTable)
register additional event names
#define PROPERTY_CONTROLLABEL
Definition: strings.hxx:75
static bool impl_isFormPageContainingForms(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage, css::uno::Reference< css::container::XIndexAccess > &_rxForms)
bool seekPage(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage)
seek to the page given.
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.
void examineControlNumberFormat(const css::uno::Reference< css::beans::XPropertySet > &_rxControl)
examines the control's number format, so later the format style can be referred
rtl::Reference< XMLTextParagraphExport > const & GetTextParagraphExport()
Definition: xmlexp.hxx:560
MapPropertySet2Map::iterator m_aCurrentPageIds
bool checkExamineControl(const css::uno::Reference< css::beans::XPropertySet > &_rxObject)
check the object given if it's a control, if so, examine it.
#define CTF_FORMS_DATA_STYLE
Definition: contextid.hxx:39
SvXMLNumFmtExport * m_pControlNumberStyles
Definition: layerexport.hxx:66
OUString getControlId(const css::uno::Reference< css::beans::XPropertySet > &_rxControl)
get the id of the given control.
OUString GetStyleName(sal_uInt32 nKey)
Definition: xmlnumfe.cxx:1887
::rtl::Reference< XMLPropertyHandlerFactory > m_xPropertyHandlerFactory
Definition: layerexport.hxx:72
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlexp.hxx:414
void examineForms(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage)
examine a forms collection.
void Export(bool bIsAutoStyle)
Definition: xmlnumfe.cxx:1836
SvXMLNumFmtExport * getControlNumberStyleExport()
returns the instance exporting our control's number styles
const Reference< XComponentContext > & m_rContext
int nCount
static const OUString & getControlNumberStyleNamePrefix()
returns the prefix to be used for control number styles
Definition: layerexport.cxx:66
sal_Int32 nElements
const XMLEventNameTranslation * g_pFormsEventTranslation
Definition: formevents.cxx:66
#define XML_STYLE_FAMILY_CONTROL_PREFIX
Definition: families.hxx:45
void exportControl(const css::uno::Reference< css::beans::XPropertySet > &_rxControl, const css::uno::Sequence< css::script::ScriptEventDescriptor > &_rEvents)
exports one single control
::std::map< css::uno::Reference< css::drawing::XDrawPage >, MapPropertySet2String > MapPropertySet2Map
Definition: layerexport.hxx:55
#define PROPERTY_COLUMNSERVICENAME
Definition: strings.hxx:105
void exportAutoStyles()
exports the auto-styles collected during the examineForms calls
#define DBG_UNHANDLED_EXCEPTION(...)
void exportAutoControlNumberStyles()
exports the automatic control number styles
MapPropertySet2Map::iterator m_aCurrentPageReferring
MapPropertySet2Map m_aControlIds
Definition: layerexport.hxx:94
#define TOOLS_WARN_EXCEPTION(area, stream)
int i
::std::map< css::uno::Reference< css::beans::XPropertySet >, OUString > MapPropertySet2String
Definition: layerexport.hxx:50
XMLEventExport & GetEventExport()
get Event export, with handlers for script types "None" and "StarBasic" already registered; other han...
Definition: xmlexp.cxx:2009
bool implMoveIterators(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage, bool _bClear)
moves the m_aCurrentPage* members to the positions specifying the given page.
const css::uno::Reference< css::uno::XComponentContext > & getComponentContext() const
Definition: xmlexp.hxx:520
virtual void exportCollectionElements(const css::uno::Reference< css::container::XIndexAccess > &_rxCollection) override
steps through a collection and exports all children of this collection
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
#define PROPERTY_CLASSID
Definition: strings.hxx:27
virtual ::rtl::Reference< SvXMLExportPropertyMapper > getStylePropertyMapper() override
#define PROPERTY_FORMATSSUPPLIER
Definition: strings.hxx:111
virtual SvXMLExport & getGlobalContext() override
void exportGridColumn(const css::uno::Reference< css::beans::XPropertySet > &_rxColumn, const css::uno::Sequence< css::script::ScriptEventDescriptor > &_rEvents)
exports one single grid column
void clear()
clear any structures which have been build in the recent examine calls...
const XMLPropertyMapEntry * getControlStylePropertyMap()
void collectGridColumnStylesAndIds(const css::uno::Reference< css::beans::XPropertySet > &_rxControl)
collects AutoStyles for grid columns
void exportForm(const css::uno::Reference< css::beans::XPropertySet > &_rxProps, const css::uno::Sequence< css::script::ScriptEventDescriptor > &_rEvents)
exports one single form
OUString getImmediateNumberStyle(const css::uno::Reference< css::beans::XPropertySet > &_rxObject)
determines the number format style for the given object without remembering it
Helper class for handling xml elements representing a form.
void exportForms(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage)
export a forms collection of a draw page
OFormLayerXMLExport_Impl(SvXMLExport &_rContext)
Definition: layerexport.cxx:72
OUString getControlNumberStyle(const css::uno::Reference< css::beans::XPropertySet > &_rxControl)
retrieves the style name for the control's number style.
#define SAL_WARN_IF(condition, area, stream)
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3405
rtl::Reference< SvXMLAutoStylePoolP > const & GetAutoStylePool()
Definition: xmlexp.hxx:576
void ensureControlNumberStyleExport()
ensures that the instance exporting our control's number styles exists
MapPropertySet2Int m_aControlNumberFormats
Smart struct to transport an Any with an index to the appropriate property-name.
Definition: maptype.hxx:122
void SetUsed(sal_uInt32 nKey)
Definition: xmlnumfe.cxx:1898
virtual OUString getObjectStyleName(const css::uno::Reference< css::beans::XPropertySet > &_rxObject) override
Helper class for handling xml elements representing a form control.
#define PROPERTY_FORMATSTRING
Definition: strings.hxx:113
MapPropertySet2String m_aGridColumnStyles
Helper class for exporting a grid column.
static bool pageContainsForms(const css::uno::Reference< css::drawing::XDrawPage > &_rxDrawPage)
determines whether the given page contains logical forms
#define PROPERTY_FORMATKEY
Definition: strings.hxx:106
void initializePropertyMaps()
::rtl::Reference< SvXMLExportPropertyMapper > m_xStyleExportMapper
Definition: layerexport.hxx:73
#define PROPERTY_LOCALE
Definition: strings.hxx:112
MapPropertySet2Map m_aReferringControls
Definition: layerexport.hxx:97
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)