LCOV - code coverage report
Current view: top level - libreoffice/xmloff/source/forms - layerexport.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 49 301 16.3 %
Date: 2012-12-17 Functions: 10 35 28.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      21             : #include <stdio.h>
      22             : #include "layerexport.hxx"
      23             : #include "strings.hxx"
      24             : #include <xmloff/xmlexp.hxx>
      25             : #include <xmloff/nmspmap.hxx>
      26             : #include "xmloff/xmlnmspe.hxx"
      27             : #include <xmloff/xmluconv.hxx>
      28             : #include <xmloff/xmlprmap.hxx>
      29             : #include <xmloff/prhdlfac.hxx>
      30             : #include "elementexport.hxx"
      31             : #include <xmloff/families.hxx>
      32             : #include <xmloff/contextid.hxx>
      33             : #include <xmloff/controlpropertyhdl.hxx>
      34             : #include <tools/diagnose_ex.h>
      35             : #include "controlpropertymap.hxx"
      36             : #include <com/sun/star/container/XIndexAccess.hpp>
      37             : #include <com/sun/star/form/XFormsSupplier2.hpp>
      38             : #include <com/sun/star/xforms/XFormsSupplier.hpp>
      39             : #include <com/sun/star/form/FormComponentType.hpp>
      40             : #include <com/sun/star/lang/XServiceInfo.hpp>
      41             : #include <com/sun/star/container/XChild.hpp>
      42             : #include <com/sun/star/script/XEventAttacherManager.hpp>
      43             : #include <com/sun/star/util/NumberFormatsSupplier.hpp>
      44             : #include "eventexport.hxx"
      45             : #include <xmloff/XMLEventExport.hxx>
      46             : #include "formevents.hxx"
      47             : #include <xmloff/xmlnumfe.hxx>
      48             : #include "xmloff/xformsexport.hxx"
      49             : #include "comphelper/processfactory.hxx"
      50             : 
      51             : #include <com/sun/star/text/XText.hpp>
      52             : 
      53             : #include <numeric>
      54             : 
      55             : //.........................................................................
      56             : namespace xmloff
      57             : {
      58             : //.........................................................................
      59             : 
      60             :     using namespace ::com::sun::star::uno;
      61             :     using namespace ::com::sun::star::awt;
      62             :     using namespace ::com::sun::star::lang;
      63             :     using namespace ::com::sun::star::beans;
      64             :     using namespace ::com::sun::star::container;
      65             :     using namespace ::com::sun::star::drawing;
      66             :     using namespace ::com::sun::star::form;
      67             :     using namespace ::com::sun::star::script;
      68             :     using namespace ::com::sun::star::util;
      69             :     using namespace ::com::sun::star::text;
      70             : 
      71             :     typedef ::com::sun::star::xforms::XFormsSupplier XXFormsSupplier;
      72             : 
      73             :     //=====================================================================
      74             :     //= OFormLayerXMLExport_Impl
      75             :     //=====================================================================
      76             :     //---------------------------------------------------------------------
      77           0 :     const ::rtl::OUString& OFormLayerXMLExport_Impl::getControlNumberStyleNamePrefix()
      78             :     {
      79           0 :         static const ::rtl::OUString s_sControlNumberStyleNamePrefix("C");
      80           0 :         return s_sControlNumberStyleNamePrefix;
      81             :     }
      82             : 
      83             :     //---------------------------------------------------------------------
      84           8 :     OFormLayerXMLExport_Impl::OFormLayerXMLExport_Impl(SvXMLExport& _rContext)
      85             :         :m_rContext(_rContext)
      86           8 :         ,m_pControlNumberStyles(NULL)
      87             :     {
      88           8 :         initializePropertyMaps();
      89             : 
      90             :         // add our style family to the export context's style pool
      91           8 :         m_xPropertyHandlerFactory = new OControlPropertyHandlerFactory();
      92           8 :         ::rtl::Reference< XMLPropertySetMapper > xStylePropertiesMapper = new XMLPropertySetMapper( getControlStylePropertyMap(), m_xPropertyHandlerFactory.get() );
      93           8 :         m_xStyleExportMapper = new OFormComponentStyleExportMapper( xStylePropertiesMapper.get() );
      94             : 
      95             :         // our style family
      96             :         m_rContext.GetAutoStylePool()->AddFamily(
      97           8 :             XML_STYLE_FAMILY_CONTROL_ID, token::GetXMLToken(token::XML_PARAGRAPH),
      98             :             m_xStyleExportMapper.get(),
      99             :             ::rtl::OUString(  XML_STYLE_FAMILY_CONTROL_PREFIX )
     100          16 :         );
     101             : 
     102             :         // add our event translation table
     103           8 :         m_rContext.GetEventExport().AddTranslationTable(g_pFormsEventTranslation);
     104             : 
     105           8 :         clear();
     106           8 :     }
     107             : 
     108          16 :     OFormLayerXMLExport_Impl::~OFormLayerXMLExport_Impl()
     109             :     {
     110          16 :     }
     111             : 
     112             :     //---------------------------------------------------------------------
     113           4 :     sal_Bool OFormLayerXMLExport_Impl::impl_isFormPageContainingForms(const Reference< XDrawPage >& _rxDrawPage, Reference< XIndexAccess >& _rxForms)
     114             :     {
     115           4 :         Reference< XFormsSupplier2 > xFormsSupp(_rxDrawPage, UNO_QUERY);
     116             :         OSL_ENSURE(xFormsSupp.is(), "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid draw page (no XFormsSupplier)! Doin' nothing!");
     117           4 :         if (!xFormsSupp.is())
     118           0 :             return sal_False;
     119             : 
     120           4 :         if ( !xFormsSupp->hasForms() )
     121             :             // nothing to do at all
     122           4 :             return sal_False;
     123             : 
     124           0 :         _rxForms = Reference< XIndexAccess >(xFormsSupp->getForms(), UNO_QUERY);
     125           0 :         Reference< XServiceInfo > xSI(_rxForms, UNO_QUERY); // order is important!
     126             :         OSL_ENSURE(xSI.is(), "OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (must not be NULL and must have a ServiceInfo)!");
     127           0 :         if (!xSI.is())
     128           0 :             return sal_False;
     129             : 
     130           0 :         if (!xSI->supportsService(SERVICE_FORMSCOLLECTION))
     131             :         {
     132             :             OSL_FAIL("OFormLayerXMLExport_Impl::impl_isFormPageContainingForms: invalid collection (is no com.sun.star.form.Forms)!");
     133             :             // nothing to do
     134           0 :             return sal_False;
     135             :         }
     136           0 :         return sal_True;
     137             :     }
     138             : 
     139             :     //---------------------------------------------------------------------
     140           0 :     void OFormLayerXMLExport_Impl::exportGridColumn(const Reference< XPropertySet >& _rxColumn,
     141             :         const Sequence< ScriptEventDescriptor >& _rEvents)
     142             :     {
     143             :         // do the exporting
     144           0 :         OColumnExport aExportImpl(*this, _rxColumn, getControlId( _rxColumn ), _rEvents);
     145           0 :         aExportImpl.doExport();
     146           0 :     }
     147             : 
     148             :     //---------------------------------------------------------------------
     149           0 :     void OFormLayerXMLExport_Impl::exportControl(const Reference< XPropertySet >& _rxControl,
     150             :         const Sequence< ScriptEventDescriptor >& _rEvents)
     151             :     {
     152             :         // the list of the referring controls
     153           0 :         ::rtl::OUString sReferringControls;
     154           0 :         MapPropertySet2String::const_iterator aReferring = m_aCurrentPageReferring->second.find(_rxControl);
     155           0 :         if (aReferring != m_aCurrentPageReferring->second.end())
     156           0 :             sReferringControls = aReferring->second;
     157             : 
     158             :         // the control id (should already have been created in examineForms)
     159           0 :         ::rtl::OUString sControlId( getControlId( _rxControl ) );
     160             : 
     161             :         // do the exporting
     162           0 :         OControlExport aExportImpl(*this, _rxControl, sControlId, sReferringControls, _rEvents);
     163           0 :         aExportImpl.doExport();
     164           0 :     }
     165             : 
     166             :     //---------------------------------------------------------------------
     167           0 :     void OFormLayerXMLExport_Impl::exportForm(const Reference< XPropertySet >& _rxProps,
     168             :         const Sequence< ScriptEventDescriptor >& _rEvents)
     169             :     {
     170             :         OSL_ENSURE(_rxProps.is(), "OFormLayerXMLExport_Impl::exportForm: invalid property set!");
     171           0 :         OFormExport aAttributeHandler(*this, _rxProps, _rEvents);
     172           0 :         aAttributeHandler.doExport();
     173           0 :     }
     174             : 
     175             :     //---------------------------------------------------------------------
     176           0 :     ::rtl::Reference< SvXMLExportPropertyMapper > OFormLayerXMLExport_Impl::getStylePropertyMapper()
     177             :     {
     178           0 :         return m_xStyleExportMapper;
     179             :     }
     180             : 
     181             :     //---------------------------------------------------------------------
     182           0 :     SvXMLExport& OFormLayerXMLExport_Impl::getGlobalContext()
     183             :     {
     184           0 :         return m_rContext;
     185             :     }
     186             : 
     187             :     //---------------------------------------------------------------------
     188           0 :     void OFormLayerXMLExport_Impl::exportCollectionElements(const Reference< XIndexAccess >& _rxCollection)
     189             :     {
     190             :         // step through all the elements of the collection
     191           0 :         sal_Int32 nElements = _rxCollection->getCount();
     192             : 
     193           0 :         Reference< XEventAttacherManager > xElementEventManager(_rxCollection, UNO_QUERY);
     194           0 :         Sequence< ScriptEventDescriptor > aElementEvents;
     195             : 
     196           0 :         Reference< XPropertySetInfo > xPropsInfo;
     197           0 :         Reference< XIndexAccess > xCurrentContainer;
     198           0 :         for (sal_Int32 i=0; i<nElements; ++i)
     199             :         {
     200             :             try
     201             :             {
     202             :                 // extract the current element
     203           0 :                 Reference< XPropertySet > xCurrentProps( _rxCollection->getByIndex(i), UNO_QUERY );
     204             :                 OSL_ENSURE(xCurrentProps.is(), "OFormLayerXMLExport_Impl::exportCollectionElements: invalid child element, skipping!");
     205           0 :                 if (!xCurrentProps.is())
     206           0 :                     continue;
     207             : 
     208             :                 // check if there is a ClassId property on the current element. If so, we assume it to be a control
     209           0 :                 xPropsInfo = xCurrentProps->getPropertySetInfo();
     210             :                 OSL_ENSURE(xPropsInfo.is(), "OFormLayerXMLExport_Impl::exportCollectionElements: no property set info!");
     211           0 :                 if (!xPropsInfo.is())
     212             :                     // without this, a lot of stuff in the export routines may fail
     213           0 :                     continue;
     214             : 
     215             :                 // if the element is part of a ignore list, we are not allowed to export it
     216           0 :                 if ( m_aIgnoreList.end() != m_aIgnoreList.find( xCurrentProps ) )
     217           0 :                     continue;
     218             : 
     219           0 :                 if (xElementEventManager.is())
     220           0 :                     aElementEvents = xElementEventManager->getScriptEvents(i);
     221             : 
     222           0 :                 if (xPropsInfo->hasPropertyByName(PROPERTY_COLUMNSERVICENAME))
     223             :                 {
     224           0 :                     exportGridColumn(xCurrentProps, aElementEvents);
     225             :                 }
     226           0 :                 else if (xPropsInfo->hasPropertyByName(PROPERTY_CLASSID))
     227             :                 {
     228           0 :                     exportControl(xCurrentProps, aElementEvents);
     229             :                 }
     230             :                 else
     231             :                 {
     232           0 :                     exportForm(xCurrentProps, aElementEvents);
     233           0 :                 }
     234             :             }
     235           0 :             catch(Exception&)
     236             :             {
     237             :                 OSL_FAIL("OFormLayerXMLExport_Impl::exportCollectionElements: caught an exception ... skipping the current element!");
     238           0 :                 continue;
     239             :             }
     240           0 :         }
     241           0 :     }
     242             : 
     243             :     //---------------------------------------------------------------------
     244           0 :     ::rtl::OUString OFormLayerXMLExport_Impl::getObjectStyleName( const Reference< XPropertySet >& _rxObject )
     245             :     {
     246           0 :         ::rtl::OUString aObjectStyle;
     247             : 
     248           0 :         MapPropertySet2String::const_iterator aObjectStylePos = m_aGridColumnStyles.find( _rxObject );
     249           0 :         if ( m_aGridColumnStyles.end() != aObjectStylePos )
     250           0 :             aObjectStyle = aObjectStylePos->second;
     251           0 :         return aObjectStyle;
     252             :     }
     253             : 
     254             :     //---------------------------------------------------------------------
     255           8 :     void OFormLayerXMLExport_Impl::clear()
     256             :     {
     257           8 :         m_aControlIds.clear();
     258           8 :         m_aReferringControls.clear();
     259           8 :         m_aCurrentPageIds = m_aControlIds.end();
     260           8 :         m_aCurrentPageReferring = m_aReferringControls.end();
     261             : 
     262           8 :         m_aControlNumberFormats.clear();
     263           8 :         m_aGridColumnStyles.clear();
     264             : 
     265           8 :         m_aIgnoreList.clear();
     266           8 :     }
     267             : 
     268             :     //---------------------------------------------------------------------
     269           4 :     void OFormLayerXMLExport_Impl::exportAutoControlNumberStyles()
     270             :     {
     271           4 :         if ( m_pControlNumberStyles )
     272           0 :             m_pControlNumberStyles->Export( sal_True );
     273           4 :     }
     274             : 
     275             :     //---------------------------------------------------------------------
     276           8 :     void OFormLayerXMLExport_Impl::exportAutoStyles()
     277             :     {
     278             :         m_rContext.GetAutoStylePool()->exportXML(
     279             :             XML_STYLE_FAMILY_CONTROL_ID,
     280           8 :             m_rContext.GetDocHandler(),
     281           8 :             m_rContext.GetMM100UnitConverter(),
     282           8 :             m_rContext.GetNamespaceMap()
     283           8 :         );
     284           8 :     }
     285             : 
     286             :     //---------------------------------------------------------------------
     287           0 :     void OFormLayerXMLExport_Impl::exportForms(const Reference< XDrawPage >& _rxDrawPage)
     288             :     {
     289             :         // get the forms collection of the page
     290           0 :         Reference< XIndexAccess > xCollectionIndex;
     291           0 :         if (!impl_isFormPageContainingForms(_rxDrawPage, xCollectionIndex))
     292           0 :             return;
     293             : 
     294             : #if OSL_DEBUG_LEVEL > 0
     295             :         sal_Bool bPageIsKnown =
     296             : #endif
     297           0 :             implMoveIterators(_rxDrawPage, sal_False);
     298             :         OSL_ENSURE(bPageIsKnown, "OFormLayerXMLExport_Impl::exportForms: exporting a page which has not been examined!");
     299             : 
     300             :         // export forms collection
     301           0 :         exportCollectionElements(xCollectionIndex);
     302             :     }
     303             : 
     304             :     //---------------------------------------------------------------------
     305           0 :     void OFormLayerXMLExport_Impl::exportXForms() const
     306             :     {
     307             :         // export XForms models
     308           0 :         ::exportXForms( m_rContext );
     309           0 :     }
     310             : 
     311             :     //---------------------------------------------------------------------
     312           4 :     bool OFormLayerXMLExport_Impl::pageContainsForms( const Reference< XDrawPage >& _rxDrawPage ) const
     313             :     {
     314           4 :         Reference< XFormsSupplier2 > xFormsSupp( _rxDrawPage, UNO_QUERY );
     315             :         DBG_ASSERT( xFormsSupp.is(), "OFormLayerXMLExport_Impl::pageContainsForms: no XFormsSupplier2!" );
     316           4 :         return xFormsSupp.is() && xFormsSupp->hasForms();
     317             :     }
     318             : 
     319             :     //---------------------------------------------------------------------
     320           4 :     bool OFormLayerXMLExport_Impl::documentContainsXForms() const
     321             :     {
     322           4 :         Reference< XXFormsSupplier > xXFormSupp( m_rContext.GetModel(), UNO_QUERY );
     323           4 :         Reference< XNameContainer > xForms;
     324           4 :         if ( xXFormSupp.is() )
     325           4 :             xForms = xXFormSupp->getXForms();
     326           4 :         return xForms.is() && xForms->hasElements();
     327             :     }
     328             : 
     329             :     //---------------------------------------------------------------------
     330           0 :     sal_Bool OFormLayerXMLExport_Impl::implMoveIterators(const Reference< XDrawPage >& _rxDrawPage, sal_Bool _bClear)
     331             :     {
     332           0 :         if (!_rxDrawPage.is())
     333           0 :             return false;
     334             : 
     335           0 :         sal_Bool bKnownPage = sal_False;
     336             : 
     337             :         // the one for the ids
     338           0 :         m_aCurrentPageIds = m_aControlIds.find(_rxDrawPage);
     339           0 :         if (m_aControlIds.end() == m_aCurrentPageIds)
     340             :         {
     341           0 :             m_aControlIds[_rxDrawPage] = MapPropertySet2String();
     342           0 :             m_aCurrentPageIds = m_aControlIds.find(_rxDrawPage);
     343             :         }
     344             :         else
     345             :         {
     346           0 :             bKnownPage = sal_True;
     347           0 :             if (_bClear && !m_aCurrentPageIds->second.empty() )
     348           0 :                 m_aCurrentPageIds->second.clear();
     349             :         }
     350             : 
     351             :         // the one for the ids of the referring controls
     352           0 :         m_aCurrentPageReferring = m_aReferringControls.find(_rxDrawPage);
     353           0 :         if (m_aReferringControls.end() == m_aCurrentPageReferring)
     354             :         {
     355           0 :             m_aReferringControls[_rxDrawPage] = MapPropertySet2String();
     356           0 :             m_aCurrentPageReferring = m_aReferringControls.find(_rxDrawPage);
     357             :         }
     358             :         else
     359             :         {
     360           0 :             bKnownPage = sal_True;
     361           0 :             if (_bClear && !m_aCurrentPageReferring->second.empty() )
     362           0 :                 m_aCurrentPageReferring->second.clear();
     363             :         }
     364           0 :         return bKnownPage;
     365             :     }
     366             : 
     367             :     //---------------------------------------------------------------------
     368           0 :     sal_Bool OFormLayerXMLExport_Impl::seekPage(const Reference< XDrawPage >& _rxDrawPage)
     369             :     {
     370           0 :         sal_Bool bKnownPage = implMoveIterators( _rxDrawPage, sal_False );
     371           0 :         if ( bKnownPage )
     372           0 :             return sal_True;
     373             : 
     374             :         // if the page is not yet known, this does not automatically mean that it has
     375             :         // not been examined. Instead, examineForms returns silently and successfully
     376             :         // if a page is a XFormsPageSupplier2, but does not have a forms collection
     377             :         // (This behaviour of examineForms is a performance optimization, to not force
     378             :         // the page to create a forms container just to see that it's empty.)
     379             : 
     380             :         // So, in such a case, seekPage is considered to be successfull, too, though the
     381             :         // page was not yet known
     382           0 :         Reference< XFormsSupplier2 > xFormsSupp( _rxDrawPage, UNO_QUERY );
     383           0 :         if ( xFormsSupp.is() && !xFormsSupp->hasForms() )
     384           0 :             return sal_True;
     385             : 
     386             :         // anything else means that the page has not been examined before, or it's no
     387             :         // valid form page. Both cases are Bad (TM).
     388           0 :         return sal_False;
     389             :     }
     390             : 
     391             :     //---------------------------------------------------------------------
     392           0 :     ::rtl::OUString OFormLayerXMLExport_Impl::getControlId(const Reference< XPropertySet >& _rxControl)
     393             :     {
     394           0 :         if (m_aCurrentPageIds == m_aControlIds.end())
     395           0 :             return ::rtl::OUString();
     396             : 
     397             :         OSL_ENSURE(m_aCurrentPageIds->second.end() != m_aCurrentPageIds->second.find(_rxControl),
     398             :             "OFormLayerXMLExport_Impl::getControlId: can not find the control!");
     399           0 :         return m_aCurrentPageIds->second[_rxControl];
     400             :     }
     401             : 
     402             :     //---------------------------------------------------------------------
     403           0 :     ::rtl::OUString OFormLayerXMLExport_Impl::getImmediateNumberStyle( const Reference< XPropertySet >& _rxObject )
     404             :     {
     405           0 :         ::rtl::OUString sNumberStyle;
     406             : 
     407           0 :         sal_Int32 nOwnFormatKey = implExamineControlNumberFormat( _rxObject );
     408           0 :         if ( -1 != nOwnFormatKey )
     409           0 :             sNumberStyle = getControlNumberStyleExport()->GetStyleName( nOwnFormatKey );
     410             : 
     411           0 :         return sNumberStyle;
     412             :     }
     413             : 
     414             :     //---------------------------------------------------------------------
     415           0 :     ::rtl::OUString OFormLayerXMLExport_Impl::getControlNumberStyle( const Reference< XPropertySet >& _rxControl )
     416             :     {
     417           0 :         ::rtl::OUString sNumberStyle;
     418             : 
     419           0 :         ConstMapPropertySet2IntIterator aControlFormatPos = m_aControlNumberFormats.find(_rxControl);
     420           0 :         if (m_aControlNumberFormats.end() != aControlFormatPos)
     421             :         {
     422             :             OSL_ENSURE(m_pControlNumberStyles, "OFormLayerXMLExport_Impl::getControlNumberStyle: have a control which has a format style, but no style exporter!");
     423           0 :             sNumberStyle = getControlNumberStyleExport()->GetStyleName(aControlFormatPos->second);
     424             :         }
     425             :         // it's allowed to ask for a control which does not have format information.
     426             :         // (This is for performance reasons)
     427             : 
     428           0 :         return sNumberStyle;
     429             :     }
     430             : 
     431             :     //---------------------------------------------------------------------
     432           4 :     void OFormLayerXMLExport_Impl::examineForms(const Reference< XDrawPage >& _rxDrawPage)
     433             :     {
     434             :         // get the forms collection of the page
     435           4 :         Reference< XIndexAccess > xCollectionIndex;
     436           4 :         if (!impl_isFormPageContainingForms(_rxDrawPage, xCollectionIndex))
     437           4 :             return;
     438             : 
     439             :         // move the iterator which specify the currently handled page
     440             : #if OSL_DEBUG_LEVEL > 0
     441             :         sal_Bool bPageIsKnown =
     442             : #endif
     443           0 :             implMoveIterators(_rxDrawPage, sal_True);
     444             :         OSL_ENSURE(!bPageIsKnown, "OFormLayerXMLExport_Impl::examineForms: examining a page twice!");
     445             : 
     446           0 :         ::std::stack< Reference< XIndexAccess > >   aContainerHistory;
     447           0 :         ::std::stack< sal_Int32 >                   aIndexHistory;
     448             : 
     449           0 :         Reference< XIndexAccess > xLoop = xCollectionIndex;
     450           0 :         sal_Int32 nChildPos = 0;
     451           0 :         do
     452             :         {
     453           0 :             if (nChildPos < xLoop->getCount())
     454             :             {
     455           0 :                 Reference< XPropertySet > xCurrent( xLoop->getByIndex( nChildPos ), UNO_QUERY );
     456             :                 OSL_ENSURE(xCurrent.is(), "OFormLayerXMLExport_Impl::examineForms: invalid child object");
     457           0 :                 if (!xCurrent.is())
     458           0 :                     continue;
     459             : 
     460           0 :                 if (!checkExamineControl(xCurrent))
     461             :                 {
     462             :                     // step down
     463           0 :                     Reference< XIndexAccess > xNextContainer(xCurrent, UNO_QUERY);
     464             :                     OSL_ENSURE(xNextContainer.is(), "OFormLayerXMLExport_Impl::examineForms: what the heck is this ... no control, no container?");
     465           0 :                     aContainerHistory.push(xLoop);
     466           0 :                     aIndexHistory.push(nChildPos);
     467             : 
     468           0 :                     xLoop = xNextContainer;
     469           0 :                     nChildPos = -1; // will be incremented below
     470             :                 }
     471           0 :                 ++nChildPos;
     472             :             }
     473             :             else
     474             :             {
     475             :                 // step up
     476           0 :                 while ((nChildPos >= xLoop->getCount()) && !aContainerHistory.empty() )
     477             :                 {
     478           0 :                     xLoop = aContainerHistory.top();
     479           0 :                     aContainerHistory.pop();
     480           0 :                     nChildPos = aIndexHistory.top();
     481           0 :                     aIndexHistory.pop();
     482             : 
     483           0 :                     ++nChildPos;
     484             :                 }
     485           0 :                 if (nChildPos >= xLoop->getCount())
     486             :                     // exited the loop above because we have no history anymore (0 == aContainerHistory.size()),
     487             :                     // and on the current level there are no more children
     488             :                     // -> leave
     489           0 :                     break;
     490             :             }
     491             :         }
     492           0 :         while (xLoop.is());
     493             :     }
     494             : 
     495             :     //---------------------------------------------------------------------
     496             :     namespace
     497             :     {
     498             :         struct AccumulateSize : public ::std::binary_function< size_t, MapPropertySet2Map::value_type, size_t >
     499             :         {
     500           0 :             size_t operator()( size_t _size, const MapPropertySet2Map::value_type& _map ) const
     501             :             {
     502           0 :                 return _size + _map.second.size();
     503             :             }
     504             :         };
     505             : 
     506           0 :         ::rtl::OUString lcl_findFreeControlId( const MapPropertySet2Map& _rAllPagesControlIds )
     507             :         {
     508           0 :             static const ::rtl::OUString sControlIdBase(  "control"  );
     509           0 :             ::rtl::OUString sControlId = sControlIdBase;
     510             : 
     511           0 :             size_t nKnownControlCount = ::std::accumulate( _rAllPagesControlIds.begin(), _rAllPagesControlIds.end(), (size_t)0, AccumulateSize() );
     512           0 :             sControlId += ::rtl::OUString::valueOf( (sal_Int32)nKnownControlCount + 1 );
     513             : 
     514             :         #ifdef DBG_UTIL
     515             :             // Check if the id is already used. It shouldn't, as we currently have no mechanism for removing entries
     516             :             // from the map, so the approach used above (take the accumulated map size) should be sufficient. But if
     517             :             // somebody changes this (e.g. allows removing entries from the map), the assertion below probably will fail.
     518             :             for (   MapPropertySet2Map::const_iterator outer = _rAllPagesControlIds.begin();
     519             :                     outer != _rAllPagesControlIds.end();
     520             :                     ++outer
     521             :                 )
     522             :                 for (   MapPropertySet2String::const_iterator inner = outer->second.begin();
     523             :                         inner != outer->second.end();
     524             :                         ++inner
     525             :                     )
     526             :                 {
     527             :                     OSL_ENSURE( inner->second != sControlId,
     528             :                         "lcl_findFreeControlId: auto-generated control ID is already used!" );
     529             :                 }
     530             :         #endif
     531           0 :             return sControlId;
     532             :         }
     533             :     }
     534             : 
     535             :     //---------------------------------------------------------------------
     536           0 :     sal_Bool OFormLayerXMLExport_Impl::checkExamineControl(const Reference< XPropertySet >& _rxObject)
     537             :     {
     538           0 :         Reference< XPropertySetInfo > xCurrentInfo = _rxObject->getPropertySetInfo();
     539             :         OSL_ENSURE(xCurrentInfo.is(), "OFormLayerXMLExport_Impl::checkExamineControl: no property set info");
     540             : 
     541           0 :         sal_Bool bIsControl = xCurrentInfo->hasPropertyByName( PROPERTY_CLASSID );
     542           0 :         if (bIsControl)
     543             :         {
     544             :             // ----------------------------------
     545             :             // generate a new control id
     546             : 
     547             :             // find a free id
     548           0 :             ::rtl::OUString sCurrentId = lcl_findFreeControlId( m_aControlIds );
     549             :             // add it to the map
     550           0 :             m_aCurrentPageIds->second[_rxObject] = sCurrentId;
     551             : 
     552             :             // ----------------------------------
     553             :             // check if this control has a "LabelControl" property referring another control
     554           0 :             if ( xCurrentInfo->hasPropertyByName( PROPERTY_CONTROLLABEL ) )
     555             :             {
     556           0 :                 Reference< XPropertySet > xCurrentReference( _rxObject->getPropertyValue( PROPERTY_CONTROLLABEL ), UNO_QUERY );
     557           0 :                 if (xCurrentReference.is())
     558             :                 {
     559           0 :                     ::rtl::OUString& sReferencedBy = m_aCurrentPageReferring->second[xCurrentReference];
     560           0 :                     if (!sReferencedBy.isEmpty())
     561             :                         // it's not the first _rxObject referring to the xCurrentReference
     562             :                         // -> separate the id
     563           0 :                         sReferencedBy += ::rtl::OUString(",");
     564           0 :                     sReferencedBy += sCurrentId;
     565           0 :                 }
     566             :             }
     567             : 
     568             :             // ----------------------------------
     569             :             // check if the control needs a number format style
     570           0 :             if ( xCurrentInfo->hasPropertyByName( PROPERTY_FORMATKEY ) )
     571             :             {
     572           0 :                 examineControlNumberFormat(_rxObject);
     573             :             }
     574             : 
     575             :             // ----------------------------------
     576             :             // check if it's a control providing text
     577           0 :             Reference< XText > xControlText( _rxObject, UNO_QUERY );
     578           0 :             if ( xControlText.is() )
     579             :             {
     580           0 :                 m_rContext.GetTextParagraphExport()->collectTextAutoStyles( xControlText );
     581             :             }
     582             : 
     583             :             // ----------------------------------
     584             :             // check if it is a grid control - in this case, we need special handling for the columns
     585           0 :             sal_Int16 nControlType = FormComponentType::CONTROL;
     586           0 :             _rxObject->getPropertyValue( PROPERTY_CLASSID ) >>= nControlType;
     587           0 :             if ( FormComponentType::GRIDCONTROL == nControlType )
     588             :             {
     589           0 :                 collectGridColumnStylesAndIds( _rxObject );
     590           0 :             }
     591             :         }
     592             : 
     593           0 :         return bIsControl;
     594             :     }
     595             : 
     596             :     //---------------------------------------------------------------------
     597           0 :     void OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds( const Reference< XPropertySet >& _rxControl )
     598             :     {
     599             :         // loop through all columns of the grid
     600             :         try
     601             :         {
     602           0 :             Reference< XIndexAccess > xContainer( _rxControl, UNO_QUERY );
     603             :             OSL_ENSURE( xContainer.is(), "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: grid control not being a container?!" );
     604           0 :             if ( !xContainer.is() )
     605           0 :                 return;
     606             : 
     607           0 :             Reference< XPropertySetInfo > xColumnPropertiesMeta;
     608             : 
     609           0 :             sal_Int32 nCount = xContainer->getCount();
     610           0 :             for ( sal_Int32 i=0; i<nCount; ++i )
     611             :             {
     612           0 :                 Reference< XPropertySet > xColumnProperties( xContainer->getByIndex( i ), UNO_QUERY );
     613             :                 OSL_ENSURE( xColumnProperties.is(), "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: invalid grid column encountered!" );
     614           0 :                 if ( !xColumnProperties.is() )
     615           0 :                     continue;
     616             : 
     617             :                 // ----------------------------------
     618             :                 // generate a new control id
     619             : 
     620             :                 // find a free id
     621           0 :                 ::rtl::OUString sCurrentId = lcl_findFreeControlId( m_aControlIds );
     622             :                 // add it to the map
     623           0 :                 m_aCurrentPageIds->second[ xColumnProperties ] = sCurrentId;
     624             : 
     625             :                 // ----------------------------------
     626             :                 // determine a number style, if needed
     627           0 :                 xColumnPropertiesMeta = xColumnProperties->getPropertySetInfo();
     628             :                 // get the styles of the column
     629           0 :                 ::std::vector< XMLPropertyState > aPropertyStates = m_xStyleExportMapper->Filter( xColumnProperties );
     630             : 
     631             :                 // care for the number format, additionally
     632           0 :                 ::rtl::OUString sColumnNumberStyle;
     633           0 :                 if ( xColumnPropertiesMeta.is() && xColumnPropertiesMeta->hasPropertyByName( PROPERTY_FORMATKEY ) )
     634           0 :                     sColumnNumberStyle = getImmediateNumberStyle( xColumnProperties );
     635             : 
     636           0 :                 if ( !sColumnNumberStyle.isEmpty() )
     637             :                 {   // the column indeed has a formatting
     638           0 :                     sal_Int32 nStyleMapIndex = m_xStyleExportMapper->getPropertySetMapper()->FindEntryIndex( CTF_FORMS_DATA_STYLE );
     639             :                         // TODO: move this to the ctor
     640             :                     OSL_ENSURE ( -1 != nStyleMapIndex, "XMLShapeExport::collectShapeAutoStyles: could not obtain the index for our context id!");
     641             : 
     642           0 :                     XMLPropertyState aNumberStyleState( nStyleMapIndex, makeAny( sColumnNumberStyle ) );
     643           0 :                     aPropertyStates.push_back( aNumberStyleState );
     644             :                 }
     645             : 
     646             : #if OSL_DEBUG_LEVEL > 0
     647             :                 ::std::vector< XMLPropertyState >::const_iterator aHaveALook = aPropertyStates.begin();
     648             :                 for ( ; aHaveALook != aPropertyStates.end(); ++aHaveALook )
     649             :                 {
     650             :                     (void)aHaveALook;
     651             :                 }
     652             : #endif
     653             : 
     654             :                 // ----------------------------------
     655             :                 // determine the column style
     656             : 
     657           0 :                 if ( !aPropertyStates.empty() )
     658             :                 {   // add to the style pool
     659           0 :                     ::rtl::OUString sColumnStyleName = m_rContext.GetAutoStylePool()->Add( XML_STYLE_FAMILY_CONTROL_ID, aPropertyStates );
     660             : 
     661             :                     OSL_ENSURE( m_aGridColumnStyles.end() == m_aGridColumnStyles.find( xColumnProperties ),
     662             :                         "OFormLayerXMLExport_Impl::collectGridColumnStylesAndIds: already have a style for this column!" );
     663             : 
     664           0 :                     m_aGridColumnStyles.insert( MapPropertySet2String::value_type( xColumnProperties, sColumnStyleName ) );
     665             :                 }
     666           0 :             }
     667             :         }
     668           0 :         catch( const Exception& )
     669             :         {
     670             :             DBG_UNHANDLED_EXCEPTION();
     671             :         }
     672             :     }
     673             : 
     674             :     //---------------------------------------------------------------------
     675           0 :     sal_Int32 OFormLayerXMLExport_Impl::implExamineControlNumberFormat( const Reference< XPropertySet >& _rxObject )
     676             :     {
     677             :         // get the format key relative to our own formats supplier
     678           0 :         sal_Int32 nOwnFormatKey = ensureTranslateFormat( _rxObject );
     679             : 
     680           0 :         if ( -1 != nOwnFormatKey )
     681             :             // tell the exporter that we used this format
     682           0 :             getControlNumberStyleExport()->SetUsed( nOwnFormatKey );
     683             : 
     684           0 :         return nOwnFormatKey;
     685             :     }
     686             : 
     687             :     //---------------------------------------------------------------------
     688           0 :     void OFormLayerXMLExport_Impl::examineControlNumberFormat( const Reference< XPropertySet >& _rxControl )
     689             :     {
     690           0 :         sal_Int32 nOwnFormatKey = implExamineControlNumberFormat( _rxControl );
     691             : 
     692           0 :         if ( -1 == nOwnFormatKey )
     693             :             // nothing to do, the number format of this control is void
     694           0 :             return;
     695             : 
     696             :         // remember the format key for this control (we'll be asked in getControlNumberStyle for this)
     697             :         OSL_ENSURE(m_aControlNumberFormats.end() == m_aControlNumberFormats.find(_rxControl),
     698             :             "OFormLayerXMLExport_Impl::examineControlNumberFormat: already handled this control!");
     699           0 :         m_aControlNumberFormats[_rxControl] = nOwnFormatKey;
     700             :     }
     701             : 
     702             :     //---------------------------------------------------------------------
     703           0 :     sal_Int32 OFormLayerXMLExport_Impl::ensureTranslateFormat(const Reference< XPropertySet >& _rxFormattedControl)
     704             :     {
     705           0 :         ensureControlNumberStyleExport();
     706             :         OSL_ENSURE(m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: no own formats supplier!");
     707             :             // (should have been created in ensureControlNumberStyleExport)
     708             : 
     709           0 :         sal_Int32 nOwnFormatKey = -1;
     710             : 
     711             :         // the format key (relative to the control's supplier)
     712           0 :         sal_Int32 nControlFormatKey = -1;
     713           0 :         Any aControlFormatKey = _rxFormattedControl->getPropertyValue(PROPERTY_FORMATKEY);
     714           0 :         if (aControlFormatKey >>= nControlFormatKey)
     715             :         {
     716             :             // the control's number format
     717           0 :             Reference< XNumberFormatsSupplier > xControlFormatsSupplier;
     718           0 :             _rxFormattedControl->getPropertyValue(PROPERTY_FORMATSSUPPLIER) >>= xControlFormatsSupplier;
     719           0 :             Reference< XNumberFormats > xControlFormats;
     720           0 :             if (xControlFormatsSupplier.is())
     721           0 :                 xControlFormats = xControlFormatsSupplier->getNumberFormats();
     722             :             OSL_ENSURE(xControlFormats.is(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: formatted control without supplier!");
     723             : 
     724             :             // obtain the persistent (does not depend on the formats supplier) representation of the control's format
     725           0 :             Locale aFormatLocale;
     726           0 :             ::rtl::OUString sFormatDescription;
     727           0 :             if (xControlFormats.is())
     728             :             {
     729           0 :                 Reference< XPropertySet > xControlFormat = xControlFormats->getByKey(nControlFormatKey);
     730             : 
     731           0 :                 xControlFormat->getPropertyValue(PROPERTY_LOCALE)       >>= aFormatLocale;
     732           0 :                 xControlFormat->getPropertyValue(PROPERTY_FORMATSTRING) >>= sFormatDescription;
     733             :             }
     734             : 
     735             :             // check if our own formats collection already knows the format
     736           0 :             nOwnFormatKey = m_xControlNumberFormats->queryKey(sFormatDescription, aFormatLocale, sal_False);
     737           0 :             if (-1 == nOwnFormatKey)
     738             :             {   // no, we don't
     739             :                 // -> create a new format
     740           0 :                 nOwnFormatKey = m_xControlNumberFormats->addNew(sFormatDescription, aFormatLocale);
     741             :             }
     742           0 :             OSL_ENSURE(-1 != nOwnFormatKey, "OFormLayerXMLExport_Impl::ensureTranslateFormat: could not translate the controls format key!");
     743             :         }
     744             :         else
     745             :             OSL_ENSURE(!aControlFormatKey.hasValue(), "OFormLayerXMLExport_Impl::ensureTranslateFormat: invalid number format property value!");
     746             : 
     747           0 :         return nOwnFormatKey;
     748             :     }
     749             : 
     750             :     //---------------------------------------------------------------------
     751           0 :     void OFormLayerXMLExport_Impl::ensureControlNumberStyleExport()
     752             :     {
     753           0 :         if (!m_pControlNumberStyles)
     754             :         {
     755             :             // create our number formats supplier (if necessary)
     756           0 :             Reference< XNumberFormatsSupplier > xFormatsSupplier;
     757             : 
     758             :             OSL_ENSURE(!m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: inconsistence!");
     759             :                 // the m_xControlNumberFormats and m_pControlNumberStyles should be maintained together
     760             : 
     761             :             try
     762             :             {
     763             :                 // create it for en-US (does not really matter, as we will specify a locale for every
     764             :                 // concrete language to use)
     765             :                 Locale aLocale (  ::rtl::OUString("en"),
     766             :                                                  ::rtl::OUString("US"),
     767             :                                                  ::rtl::OUString()
     768           0 :                                              );
     769           0 :                 xFormatsSupplier = NumberFormatsSupplier::createWithLocale( comphelper::getComponentContext(m_rContext.getServiceFactory()), aLocale );
     770           0 :                 m_xControlNumberFormats = xFormatsSupplier->getNumberFormats();
     771             :             }
     772           0 :             catch(const Exception&)
     773             :             {
     774             :             }
     775             : 
     776             :             OSL_ENSURE(m_xControlNumberFormats.is(), "OFormLayerXMLExport_Impl::getControlNumberStyleExport: could not obtain my default number formats!");
     777             : 
     778             :             // create the exporter
     779           0 :             m_pControlNumberStyles = new SvXMLNumFmtExport(m_rContext, xFormatsSupplier, getControlNumberStyleNamePrefix());
     780             :         }
     781           0 :     }
     782             : 
     783             :     //---------------------------------------------------------------------
     784           0 :     SvXMLNumFmtExport* OFormLayerXMLExport_Impl::getControlNumberStyleExport()
     785             :     {
     786           0 :         ensureControlNumberStyleExport();
     787           0 :         return m_pControlNumberStyles;
     788             :     }
     789             : 
     790             :     //---------------------------------------------------------------------
     791           0 :     void OFormLayerXMLExport_Impl::excludeFromExport( const Reference< XControlModel > _rxControl )
     792             :     {
     793           0 :         Reference< XPropertySet > xProps( _rxControl, UNO_QUERY );
     794             :         OSL_ENSURE( xProps.is(), "OFormLayerXMLExport_Impl::excludeFromExport: invalid control model!" );
     795             : #if OSL_DEBUG_LEVEL > 0
     796             :         ::std::pair< PropertySetBag::iterator, bool > aPos =
     797             : #endif
     798           0 :         m_aIgnoreList.insert( xProps );
     799           0 :         OSL_ENSURE( aPos.second, "OFormLayerXMLExport_Impl::excludeFromExport: element already exists in the ignore list!" );
     800           0 :     }
     801             : 
     802             : //.........................................................................
     803             : }   // namespace xmloff
     804             : //.........................................................................
     805             : 
     806             : 
     807             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10