LCOV - code coverage report
Current view: top level - chart2/source/model/main - ChartModel_Persistence.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 247 344 71.8 %
Date: 2014-11-03 Functions: 28 37 75.7 %
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             : #include "ChartModel.hxx"
      21             : #include "MediaDescriptorHelper.hxx"
      22             : #include "macros.hxx"
      23             : #include "ChartViewHelper.hxx"
      24             : #include "ChartModelHelper.hxx"
      25             : #include "AxisHelper.hxx"
      26             : #include "ThreeDHelper.hxx"
      27             : 
      28             : #include <com/sun/star/chart2/LegendPosition.hpp>
      29             : #include <com/sun/star/container/XNameAccess.hpp>
      30             : #include <com/sun/star/document/XExporter.hpp>
      31             : #include <com/sun/star/document/XImporter.hpp>
      32             : #include <com/sun/star/document/XFilter.hpp>
      33             : #include <com/sun/star/drawing/FillStyle.hpp>
      34             : #include <com/sun/star/drawing/LineStyle.hpp>
      35             : #include <com/sun/star/drawing/ProjectionMode.hpp>
      36             : #include <com/sun/star/embed/ElementModes.hpp>
      37             : #include <com/sun/star/embed/XStorage.hpp>
      38             : #include <com/sun/star/embed/StorageFactory.hpp>
      39             : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
      40             : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
      41             : #include <com/sun/star/uno/XComponentContext.hpp>
      42             : #include <com/sun/star/io/TempFile.hpp>
      43             : #include <com/sun/star/io/XSeekable.hpp>
      44             : #include <com/sun/star/ucb/CommandFailedException.hpp>
      45             : 
      46             : #include <ucbhelper/content.hxx>
      47             : #include <unotools/ucbstreamhelper.hxx>
      48             : #include <vcl/cvtgrf.hxx>
      49             : #include <comphelper/processfactory.hxx>
      50             : #include <comphelper/storagehelper.hxx>
      51             : #include <vcl/svapp.hxx>
      52             : #include <vcl/settings.hxx>
      53             : 
      54             : #include <algorithm>
      55             : #include <functional>
      56             : 
      57             : using namespace ::com::sun::star;
      58             : 
      59             : using ::com::sun::star::uno::Reference;
      60             : using ::com::sun::star::uno::Sequence;
      61             : using ::osl::MutexGuard;
      62             : 
      63             : namespace
      64             : {
      65       14148 : struct lcl_PropNameEquals : public ::std::unary_function< beans::PropertyValue, bool >
      66             : {
      67        1572 :     lcl_PropNameEquals( const OUString & rStrToCompareWith ) :
      68        1572 :             m_aStr( rStrToCompareWith )
      69        1572 :     {}
      70        3174 :     bool operator() ( const beans::PropertyValue & rProp )
      71             :     {
      72        3174 :         return rProp.Name.equals( m_aStr );
      73             :     }
      74             : private:
      75             :     OUString m_aStr;
      76             : };
      77             : 
      78             : template< typename T >
      79        1572 : T lcl_getProperty(
      80             :     const Sequence< beans::PropertyValue > & rMediaDescriptor,
      81             :     const OUString & rPropName )
      82             : {
      83        1572 :     T aResult;
      84        1572 :     if( rMediaDescriptor.getLength())
      85             :     {
      86        1572 :         OUString aPropName( rPropName );
      87        1572 :         const beans::PropertyValue * pIt = rMediaDescriptor.getConstArray();
      88        1572 :         const beans::PropertyValue * pEndIt = pIt +  + rMediaDescriptor.getLength();
      89        1572 :         pIt = ::std::find_if( pIt, pEndIt, lcl_PropNameEquals( aPropName ));
      90        1572 :         if( pIt != pEndIt )
      91        1572 :             (*pIt).Value >>= aResult;
      92             :     }
      93        1572 :     return aResult;
      94             : }
      95             : 
      96         786 : void lcl_addStorageToMediaDescriptor(
      97             :     Sequence< beans::PropertyValue > & rOutMD,
      98             :     const Reference< embed::XStorage > & xStorage )
      99             : {
     100         786 :     rOutMD.realloc( rOutMD.getLength() + 1 );
     101        1572 :     rOutMD[rOutMD.getLength() - 1] = beans::PropertyValue(
     102         786 :         "Storage", -1, uno::makeAny( xStorage ), beans::PropertyState_DIRECT_VALUE );
     103         786 : }
     104             : 
     105           0 : Reference< embed::XStorage > lcl_createStorage(
     106             :     const OUString & rURL,
     107             :     const Reference< uno::XComponentContext > & xContext,
     108             :     const Sequence< beans::PropertyValue > & rMediaDescriptor )
     109             : {
     110             :     // create new storage
     111           0 :     Reference< embed::XStorage > xStorage;
     112           0 :     if( !xContext.is())
     113           0 :         return xStorage;
     114             : 
     115             :     try
     116             :     {
     117             :         Reference< io::XStream > xStream(
     118             :             ::ucbhelper::Content( rURL, Reference< ::com::sun::star::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext()).openStream(),
     119           0 :             uno::UNO_QUERY );
     120             : 
     121           0 :         Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create( xContext ) );
     122           0 :         Sequence< uno::Any > aStorageArgs( 3 );
     123           0 :         aStorageArgs[0] <<= xStream;
     124           0 :         aStorageArgs[1] <<= embed::ElementModes::READWRITE;
     125           0 :         aStorageArgs[2] <<= rMediaDescriptor;
     126             :         xStorage.set(
     127           0 :             xStorageFact->createInstanceWithArguments( aStorageArgs ), uno::UNO_QUERY_THROW );
     128           0 :         OSL_ENSURE( xStorage.is(), "No Storage" );
     129             :     }
     130           0 :     catch(const css::ucb::ContentCreationException& rEx)
     131             :     {
     132             :         ASSERT_EXCEPTION( rEx );
     133             :     }
     134           0 :     catch(const css::ucb::CommandFailedException& rEx)
     135             :     {
     136             :         ASSERT_EXCEPTION( rEx );
     137             :     }
     138             : 
     139           0 :     return xStorage;
     140             : }
     141             : 
     142             : } // anonymous namespace
     143             : 
     144             : namespace chart
     145             : {
     146             : 
     147         786 : Reference< document::XFilter > ChartModel::impl_createFilter(
     148             :     const Sequence< beans::PropertyValue > & rMediaDescriptor )
     149             : {
     150         786 :     Reference< document::XFilter > xFilter;
     151             : 
     152             :     // find FilterName in MediaDescriptor
     153             :     OUString aFilterName(
     154        1572 :         lcl_getProperty< OUString >( rMediaDescriptor, "FilterName" ) );
     155             : 
     156             :     // if FilterName was found, get Filter from factory
     157         786 :     if( !aFilterName.isEmpty() )
     158             :     {
     159             :         try
     160             :         {
     161             :             Reference< container::XNameAccess > xFilterFact(
     162        1572 :                 m_xContext->getServiceManager()->createInstanceWithContext(
     163         786 :                     "com.sun.star.document.FilterFactory", m_xContext ),
     164         786 :                 uno::UNO_QUERY_THROW );
     165        1572 :             uno::Any aFilterProps( xFilterFact->getByName( aFilterName ));
     166        1572 :             Sequence< beans::PropertyValue > aProps;
     167             : 
     168        1572 :             if( aFilterProps.hasValue() &&
     169         786 :                 (aFilterProps >>= aProps))
     170             :             {
     171             :                 OUString aFilterServiceName(
     172         786 :                     lcl_getProperty< OUString >( aProps, "FilterService" ) );
     173             : 
     174         786 :                 if( !aFilterServiceName.isEmpty())
     175             :                 {
     176             :                     xFilter.set(
     177        1572 :                         m_xContext->getServiceManager()->createInstanceWithContext(
     178         786 :                             aFilterServiceName, m_xContext ), uno::UNO_QUERY_THROW );
     179             :                     SAL_INFO("chart2", "Filter found for service " << aFilterServiceName );
     180         786 :                 }
     181         786 :             }
     182             :         }
     183           0 :         catch( const uno::Exception & ex )
     184             :         {
     185             :             ASSERT_EXCEPTION( ex );
     186             :         }
     187             :         OSL_ENSURE( xFilter.is(), "Filter not found via factory" );
     188             :     }
     189             : 
     190             :     // fall-back: create XML-Filter
     191         786 :     if( ! xFilter.is())
     192             :     {
     193             :         OSL_TRACE( "No FilterName passed in MediaDescriptor" );
     194             :         xFilter.set(
     195           0 :             m_xContext->getServiceManager()->createInstanceWithContext(
     196           0 :                 "com.sun.star.comp.chart2.XMLFilter", m_xContext ),
     197           0 :             uno::UNO_QUERY_THROW );
     198             :     }
     199             : 
     200        1572 :     return xFilter;
     201             : }
     202             : 
     203             : // frame::XStorable2
     204             : 
     205           0 : void SAL_CALL ChartModel::storeSelf( const Sequence< beans::PropertyValue >& rMediaDescriptor )
     206             :     throw (lang::IllegalArgumentException,
     207             :            io::IOException,
     208             :            uno::RuntimeException, std::exception)
     209             : {
     210             :     // only some parameters are allowed (see also SfxBaseModel)
     211             :     // "VersionComment", "Author", "InteractionHandler", "StatusIndicator"
     212             :     // However, they are ignored here.  They would become interesting when
     213             :     // charts support a standalone format again.
     214           0 :     impl_store( rMediaDescriptor, m_xStorage );
     215           0 : }
     216             : 
     217             : // frame::XStorable (base of XStorable2)
     218           0 : sal_Bool SAL_CALL ChartModel::hasLocation()
     219             :     throw(uno::RuntimeException, std::exception)
     220             : {
     221             :     //@todo guard
     222           0 :     return !m_aResource.isEmpty();
     223             : }
     224             : 
     225           0 : OUString SAL_CALL ChartModel::getLocation()
     226             :     throw(uno::RuntimeException, std::exception)
     227             : {
     228           0 :     return impl_g_getLocation();
     229             : }
     230             : 
     231        1637 : sal_Bool SAL_CALL ChartModel::isReadonly()
     232             :     throw(uno::RuntimeException, std::exception)
     233             : {
     234             :     //@todo guard
     235        1637 :     return m_bReadOnly;
     236             : }
     237             : 
     238           0 : void SAL_CALL ChartModel::store()
     239             :     throw(io::IOException,
     240             :           uno::RuntimeException, std::exception)
     241             : {
     242           0 :     apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
     243           0 :     if(!aGuard.startApiCall(true)) //start LongLastingCall
     244           0 :         return; //behave passive if already disposed or closed or throw exception @todo?
     245             : 
     246           0 :     OUString aLocation = m_aResource;
     247             : 
     248           0 :     if( aLocation.isEmpty() )
     249           0 :         throw io::IOException( "no location specified", static_cast< ::cppu::OWeakObject* >(this));
     250             :     //@todo check whether aLocation is something like private:factory...
     251           0 :     if( m_bReadOnly )
     252           0 :         throw io::IOException( "document is read only", static_cast< ::cppu::OWeakObject* >(this));
     253             : 
     254           0 :     aGuard.clear();
     255             : 
     256             :     // store
     257           0 :     impl_store( m_aMediaDescriptor, m_xStorage );
     258             : }
     259             : 
     260           0 : void SAL_CALL ChartModel::storeAsURL(
     261             :     const OUString& rURL,
     262             :     const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
     263             :     throw(io::IOException, uno::RuntimeException, std::exception)
     264             : {
     265           0 :     apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
     266           0 :     if(!aGuard.startApiCall(true)) //start LongLastingCall
     267           0 :         return; //behave passive if already disposed or closed or throw exception @todo?
     268             : 
     269           0 :     apphelper::MediaDescriptorHelper aMediaDescriptorHelper(rMediaDescriptor);
     270             :     uno::Sequence< beans::PropertyValue > aReducedMediaDescriptor(
     271           0 :         aMediaDescriptorHelper.getReducedForModel() );
     272             : 
     273           0 :     m_bReadOnly = false;
     274           0 :     aGuard.clear();
     275             : 
     276             :     // create new storage
     277           0 :     Reference< embed::XStorage > xStorage( lcl_createStorage( rURL, m_xContext, aReducedMediaDescriptor ));
     278             : 
     279           0 :     if( xStorage.is())
     280             :     {
     281           0 :         impl_store( aReducedMediaDescriptor, xStorage );
     282           0 :         attachResource( rURL, aReducedMediaDescriptor );
     283           0 :     }
     284             : }
     285             : 
     286           0 : void SAL_CALL ChartModel::storeToURL(
     287             :     const OUString& rURL,
     288             :     const uno::Sequence< beans::PropertyValue >& rMediaDescriptor )
     289             :     throw(io::IOException,
     290             :           uno::RuntimeException, std::exception)
     291             : {
     292           0 :     apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
     293           0 :     if(!aGuard.startApiCall(true)) //start LongLastingCall
     294           0 :         return; //behave passive if already disposed or closed or throw exception @todo?
     295             :     //do not change the internal state of the document here
     296             : 
     297           0 :     aGuard.clear();
     298             : 
     299           0 :     apphelper::MediaDescriptorHelper aMediaDescriptorHelper(rMediaDescriptor);
     300             :     uno::Sequence< beans::PropertyValue > aReducedMediaDescriptor(
     301           0 :         aMediaDescriptorHelper.getReducedForModel() );
     302             : 
     303           0 :     if ( rURL == "private:stream" )
     304             :     {
     305             :         try
     306             :         {
     307           0 :             if( m_xContext.is() && aMediaDescriptorHelper.ISSET_OutputStream )
     308             :             {
     309             :                 Reference< io::XStream > xStream(
     310           0 :                     io::TempFile::create(m_xContext), uno::UNO_QUERY_THROW );
     311           0 :                 Reference< io::XInputStream > xInputStream( xStream->getInputStream());
     312             : 
     313             :                 Reference< embed::XStorage > xStorage(
     314           0 :                     ::comphelper::OStorageHelper::GetStorageFromStream( xStream, embed::ElementModes::READWRITE, m_xContext ));
     315           0 :                 if( xStorage.is())
     316             :                 {
     317           0 :                     impl_store( aReducedMediaDescriptor, xStorage );
     318             : 
     319           0 :                     Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY_THROW );
     320           0 :                     xSeekable->seek( 0 );
     321           0 :                     ::comphelper::OStorageHelper::CopyInputToOutput( xInputStream, aMediaDescriptorHelper.OutputStream );
     322           0 :                 }
     323             :             }
     324             :         }
     325           0 :         catch( const uno::Exception & ex )
     326             :         {
     327             :             ASSERT_EXCEPTION( ex );
     328             :         }
     329             :     }
     330             :     else
     331             :     {
     332             :         // create new storage
     333           0 :         Reference< embed::XStorage > xStorage( lcl_createStorage( rURL, m_xContext, aReducedMediaDescriptor ));
     334             : 
     335           0 :         if( xStorage.is())
     336           0 :             impl_store( aReducedMediaDescriptor, xStorage );
     337           0 :     }
     338             : }
     339             : 
     340         544 : void ChartModel::impl_store(
     341             :     const Sequence< beans::PropertyValue >& rMediaDescriptor,
     342             :     const Reference< embed::XStorage > & xStorage )
     343             : {
     344         544 :     Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor));
     345         544 :     if( xFilter.is() && xStorage.is())
     346             :     {
     347         544 :         Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
     348         544 :         lcl_addStorageToMediaDescriptor( aMD, xStorage );
     349             :         try
     350             :         {
     351         544 :             Reference< document::XExporter > xExporter( xFilter, uno::UNO_QUERY_THROW );
     352         544 :             xExporter->setSourceDocument( Reference< lang::XComponent >( this ));
     353         544 :             xFilter->filter( aMD );
     354             :         }
     355           0 :         catch( const uno::Exception & ex )
     356             :         {
     357             :             ASSERT_EXCEPTION( ex );
     358         544 :         }
     359             :     }
     360             :     else
     361             :     {
     362             :         OSL_FAIL( "No filter" );
     363             :     }
     364             : 
     365         544 :     setModified( sal_False );
     366             : 
     367             :     //#i66865#
     368             :     //for data change notification during chart is not loaded:
     369             :     //notify parent data provider after saving thus the parent document can store
     370             :     //the ranges for which a load and update of the chart will be necessary
     371        1088 :     Reference< beans::XPropertySet > xPropSet( m_xParent, uno::UNO_QUERY );
     372         544 :     if ( !hasInternalDataProvider() && xPropSet.is() )
     373             :     {
     374          16 :         apphelper::MediaDescriptorHelper aMDHelper(rMediaDescriptor);
     375             :         try
     376             :         {
     377          16 :             xPropSet->setPropertyValue(
     378             :                 "SavedObject",
     379          22 :                 uno::makeAny( aMDHelper.HierarchicalDocumentName ) );
     380             :         }
     381           6 :         catch ( const uno::Exception& )
     382             :         {
     383          16 :         }
     384         544 :     }
     385         544 : }
     386             : 
     387          28 : void ChartModel::insertDefaultChart()
     388             : {
     389          28 :     lockControllers();
     390          28 :     createInternalDataProvider( sal_False );
     391             :     try
     392             :     {
     393             :         // create default chart
     394          28 :         Reference< chart2::XChartTypeTemplate > xTemplate( impl_createDefaultChartTypeTemplate() );
     395          28 :         if( xTemplate.is())
     396             :         {
     397             :             try
     398             :             {
     399          28 :                 Reference< chart2::data::XDataSource > xDataSource( impl_createDefaultData() );
     400          56 :                 Sequence< beans::PropertyValue > aParam;
     401             : 
     402          28 :                 bool bSupportsCategories = xTemplate->supportsCategories();
     403          28 :                 if( bSupportsCategories )
     404             :                 {
     405          28 :                     aParam.realloc( 1 );
     406          56 :                     aParam[0] = beans::PropertyValue( "HasCategories", -1, uno::makeAny( true ),
     407          28 :                                                       beans::PropertyState_DIRECT_VALUE );
     408             :                 }
     409             : 
     410          56 :                 Reference< chart2::XDiagram > xDiagram( xTemplate->createDiagramByDataSource( xDataSource, aParam ) );
     411             : 
     412          28 :                 setFirstDiagram( xDiagram );
     413             : 
     414          28 :                 bool bIsRTL = Application::GetSettings().GetMathLayoutRTL();
     415             :                 //reverse x axis for rtl charts
     416          28 :                 if( bIsRTL )
     417           0 :                     AxisHelper::setRTLAxisLayout( AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 ) );
     418             : 
     419             :                 // create and attach legend
     420             :                 Reference< chart2::XLegend > xLegend(
     421          56 :                     m_xContext->getServiceManager()->createInstanceWithContext(
     422          56 :                         "com.sun.star.chart2.Legend", m_xContext ), uno::UNO_QUERY_THROW );
     423          56 :                 Reference< beans::XPropertySet > xLegendProperties( xLegend, uno::UNO_QUERY );
     424          28 :                 if( xLegendProperties.is() )
     425             :                 {
     426          28 :                     xLegendProperties->setPropertyValue( "FillStyle", uno::makeAny( drawing::FillStyle_NONE ));
     427          28 :                     xLegendProperties->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_NONE ));
     428          28 :                     xLegendProperties->setPropertyValue( "LineColor", uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ));  // gray30
     429          28 :                     xLegendProperties->setPropertyValue( "FillColor", uno::makeAny( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10
     430             : 
     431          28 :                     if( bIsRTL )
     432           0 :                         xLegendProperties->setPropertyValue( "AnchorPosition", uno::makeAny( chart2::LegendPosition_LINE_START ));
     433             :                 }
     434          28 :                 if(xDiagram.is())
     435          28 :                     xDiagram->setLegend( xLegend );
     436             : 
     437             :                 // set simple 3D look
     438          56 :                 Reference< beans::XPropertySet > xDiagramProperties( xDiagram, uno::UNO_QUERY );
     439          28 :                 if( xDiagramProperties.is() )
     440             :                 {
     441          28 :                     xDiagramProperties->setPropertyValue( "RightAngledAxes", uno::makeAny( sal_True ));
     442          28 :                     xDiagramProperties->setPropertyValue( "D3DScenePerspective", uno::makeAny( drawing::ProjectionMode_PARALLEL ));
     443          28 :                     ThreeDHelper::setScheme( xDiagram, ThreeDLookScheme_Realistic );
     444             :                 }
     445             : 
     446             :                 //set some new 'defaults' for wall and floor
     447          28 :                 if( xDiagram.is() )
     448             :                 {
     449          28 :                     Reference< beans::XPropertySet > xWall( xDiagram->getWall() );
     450          28 :                     if( xWall.is() )
     451             :                     {
     452          28 :                         xWall->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_SOLID ) );
     453          28 :                         xWall->setPropertyValue( "FillStyle", uno::makeAny( drawing::FillStyle_NONE ) );
     454          28 :                         xWall->setPropertyValue( "LineColor", uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30
     455          28 :                         xWall->setPropertyValue( "FillColor", uno::makeAny( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10
     456             :                     }
     457          56 :                     Reference< beans::XPropertySet > xFloor( xDiagram->getFloor() );
     458          28 :                     if( xFloor.is() )
     459             :                     {
     460          28 :                         xFloor->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_NONE ) );
     461          28 :                         xFloor->setPropertyValue( "FillStyle", uno::makeAny( drawing::FillStyle_SOLID ) );
     462          28 :                         xFloor->setPropertyValue( "LineColor", uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30
     463          28 :                         xFloor->setPropertyValue( "FillColor", uno::makeAny( static_cast< sal_Int32 >( 0xcccccc ) ) ); // gray20
     464          28 :                     }
     465             : 
     466          28 :                 }
     467             :             }
     468           0 :             catch( const uno::Exception & ex )
     469             :             {
     470             :                 ASSERT_EXCEPTION( ex );
     471             :             }
     472             :         }
     473          28 :         ChartModelHelper::setIncludeHiddenCells( false, *this );
     474             :     }
     475           0 :     catch( const uno::Exception & ex )
     476             :     {
     477             :         ASSERT_EXCEPTION( ex );
     478             :     }
     479          28 :     setModified( sal_False );
     480          28 :     unlockControllers();
     481          28 : }
     482             : 
     483             : // frame::XLoadable
     484         364 : void SAL_CALL ChartModel::initNew()
     485             :     throw (frame::DoubleInitializationException,
     486             :            io::IOException,
     487             :            uno::Exception,
     488             :            uno::RuntimeException, std::exception)
     489             : {
     490         364 : }
     491             : 
     492          10 : void SAL_CALL ChartModel::load(
     493             :     const Sequence< beans::PropertyValue >& rMediaDescriptor )
     494             :     throw (frame::DoubleInitializationException,
     495             :            io::IOException,
     496             :            uno::Exception,
     497             :            uno::RuntimeException, std::exception)
     498             : {
     499          10 :     Reference< embed::XStorage > xStorage;
     500          20 :     OUString aURL;
     501             :     try
     502             :     {
     503          10 :         apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
     504          10 :         if( aMDHelper.ISSET_Storage )
     505             :         {
     506           0 :             xStorage = aMDHelper.Storage;
     507             :         }
     508          10 :         else if( aMDHelper.ISSET_Stream ||
     509             :                  aMDHelper.ISSET_InputStream )
     510             :         {
     511          40 :             if( aMDHelper.ISSET_FilterName &&
     512          60 :                 (aMDHelper.FilterName.equals( "StarChart 5.0") ||
     513          50 :                  aMDHelper.FilterName.equals( "StarChart 4.0") ||
     514          30 :                  aMDHelper.FilterName.equals( "StarChart 3.0") ))
     515             :             {
     516           0 :                 attachResource( aMDHelper.URL, rMediaDescriptor );
     517           0 :                 impl_load( rMediaDescriptor, 0 ); // cannot create a storage from binary streams, but I do not need the storage here anyhow
     518           0 :                 m_bReadOnly = true;
     519          10 :                 return;
     520             :             }
     521             : 
     522          10 :             Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create(m_xContext) );
     523             : 
     524          10 :             if( aMDHelper.ISSET_Stream )
     525             :             {
     526             :                 // convert XStream to XStorage via the storage factory
     527           6 :                 Sequence< uno::Any > aStorageArgs( 2 );
     528           6 :                 aStorageArgs[0] <<= aMDHelper.Stream;
     529             :                 // todo: check if stream is read-only
     530           6 :                 aStorageArgs[1] <<= (embed::ElementModes::READ); //WRITE | embed::ElementModes::NOCREATE);
     531             : 
     532           6 :                 xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
     533           6 :                     uno::UNO_QUERY_THROW );
     534             :             }
     535             :             else
     536             :             {
     537             :                 OSL_ASSERT( aMDHelper.ISSET_InputStream );
     538             :                 // convert XInputStream to XStorage via the storage factory
     539           4 :                 Sequence< uno::Any > aStorageArgs( 2 );
     540           4 :                 aStorageArgs[0] <<= aMDHelper.InputStream;
     541           4 :                 aStorageArgs[1] <<= (embed::ElementModes::READ);
     542             : 
     543           4 :                 xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
     544           4 :                     uno::UNO_QUERY_THROW );
     545          10 :             }
     546             :         }
     547             : 
     548          10 :         if( aMDHelper.ISSET_URL )
     549          10 :             aURL = aMDHelper.URL;
     550             :     }
     551           0 :     catch( const uno::Exception & ex )
     552             :     {
     553             :         ASSERT_EXCEPTION( ex );
     554             :     }
     555             : 
     556          10 :     if( xStorage.is())
     557             :     {
     558          10 :         attachResource( aURL, rMediaDescriptor );
     559          10 :         impl_load( rMediaDescriptor, xStorage );
     560          10 :     }
     561             : }
     562             : 
     563         242 : void ChartModel::impl_load(
     564             :     const Sequence< beans::PropertyValue >& rMediaDescriptor,
     565             :     const Reference< embed::XStorage >& xStorage )
     566             : {
     567             :     {
     568         242 :         MutexGuard aGuard( m_aModelMutex );
     569         242 :         m_nInLoad++;
     570             :     }
     571             : 
     572         242 :     Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor ));
     573             : 
     574         242 :     if( xFilter.is())
     575             :     {
     576         242 :         Reference< document::XImporter > xImporter( xFilter, uno::UNO_QUERY_THROW );
     577         242 :         xImporter->setTargetDocument( this );
     578         484 :         Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
     579         242 :         lcl_addStorageToMediaDescriptor( aMD, xStorage );
     580             : 
     581         242 :         xFilter->filter( aMD );
     582         484 :         xFilter.clear();
     583             :     }
     584             :     else
     585             :     {
     586             :         OSL_FAIL( "loadFromStorage cannot create filter" );
     587             :     }
     588             : 
     589         242 :     if( xStorage.is() )
     590         242 :         impl_loadGraphics( xStorage );
     591             : 
     592         242 :     setModified( sal_False );
     593             : 
     594             :     // switchToStorage without notifying listeners (which shouldn't exist at
     595             :     // this time, anyway)
     596         242 :     m_xStorage = xStorage;
     597             : 
     598             :     {
     599         242 :         MutexGuard aGuard( m_aModelMutex );
     600         242 :         m_nInLoad--;
     601         242 :     }
     602         242 : }
     603             : 
     604         242 : void ChartModel::impl_loadGraphics(
     605             :     const Reference< embed::XStorage >& xStorage )
     606             : {
     607             :     try
     608             :     {
     609             :         const Reference< embed::XStorage >& xGraphicsStorage(
     610         242 :             xStorage->openStorageElement( "Pictures",
     611         466 :                                           embed::ElementModes::READ ) );
     612             : 
     613          18 :         if( xGraphicsStorage.is() )
     614             :         {
     615             :             const uno::Sequence< OUString > aElementNames(
     616          18 :                 xGraphicsStorage->getElementNames() );
     617             : 
     618          42 :             for( int i = 0; i < aElementNames.getLength(); ++i )
     619             :             {
     620          24 :                 if( xGraphicsStorage->isStreamElement( aElementNames[ i ] ) )
     621             :                 {
     622             :                     uno::Reference< io::XStream > xElementStream(
     623          24 :                         xGraphicsStorage->openStreamElement(
     624          24 :                             aElementNames[ i ],
     625          48 :                             embed::ElementModes::READ ) );
     626             : 
     627          24 :                     if( xElementStream.is() )
     628             :                     {
     629             :                         boost::scoped_ptr< SvStream > apIStm(
     630             :                             ::utl::UcbStreamHelper::CreateStream(
     631          24 :                                 xElementStream, true ) );
     632             : 
     633          24 :                         if( apIStm.get() )
     634             :                         {
     635          24 :                             Graphic aGraphic;
     636             : 
     637          24 :                             if( !GraphicConverter::Import(
     638          24 :                                     *apIStm.get(),
     639          24 :                                     aGraphic ) )
     640             :                             {
     641          24 :                                 m_aGraphicObjectVector.push_back( aGraphic );
     642          24 :                             }
     643          24 :                         }
     644          24 :                     }
     645             :                 }
     646          18 :             }
     647          18 :         }
     648             :     }
     649         224 :     catch ( const uno::Exception& )
     650             :     {
     651             :     }
     652         242 : }
     653             : 
     654             : // util::XModifiable
     655        3507 : void SAL_CALL ChartModel::impl_notifyModifiedListeners()
     656             :     throw( uno::RuntimeException)
     657             : {
     658             :     {
     659        3507 :         MutexGuard aGuard( m_aModelMutex );
     660        3507 :         m_bUpdateNotificationsPending = false;
     661             :     }
     662             : 
     663             :     //always notify the view first!
     664        3507 :     ChartViewHelper::setViewToDirtyState( this );
     665             : 
     666             :     ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
     667        3507 :         .getContainer( cppu::UnoType<util::XModifyListener>::get());
     668        3507 :     if( pIC )
     669             :     {
     670        3069 :         lang::EventObject aEvent( static_cast< lang::XComponent*>(this) );
     671        6138 :         ::cppu::OInterfaceIteratorHelper aIt( *pIC );
     672       16531 :         while( aIt.hasMoreElements() )
     673             :         {
     674       10393 :             uno::Reference< util::XModifyListener > xListener( aIt.next(), uno::UNO_QUERY );
     675       10393 :             if( xListener.is() )
     676       10393 :                 xListener->modified( aEvent );
     677       13462 :         }
     678             :     }
     679        3507 : }
     680             : 
     681        4566 : sal_Bool SAL_CALL ChartModel::isModified()
     682             :     throw(uno::RuntimeException, std::exception)
     683             : {
     684             :     //@todo guard
     685        4566 :     return m_bModified;
     686             : }
     687             : 
     688       14729 : void SAL_CALL ChartModel::setModified( sal_Bool bModified )
     689             :     throw(beans::PropertyVetoException,
     690             :           uno::RuntimeException, std::exception)
     691             : {
     692       14729 :     apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
     693       14729 :     if(!aGuard.startApiCall())//@todo ? is this a long lasting call??
     694           2 :         return; //behave passive if already disposed or closed or throw exception @todo?
     695       14727 :     m_bModified = bModified;
     696             : 
     697       14727 :     if( m_nControllerLockCount > 0 )
     698             :     {
     699       10376 :         m_bUpdateNotificationsPending = true;
     700       10376 :         return;//don't call listeners if controllers are locked
     701             :     }
     702        4351 :     aGuard.clear();
     703             : 
     704        4351 :     if(bModified)
     705        2091 :         impl_notifyModifiedListeners();
     706             : }
     707             : 
     708             : // util::XModifyBroadcaster (base of XModifiable)
     709        2146 : void SAL_CALL ChartModel::addModifyListener(
     710             :     const uno::Reference< util::XModifyListener >& xListener )
     711             :     throw(uno::RuntimeException, std::exception)
     712             : {
     713        2146 :     if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
     714        2146 :         return; //behave passive if already disposed or closed
     715             : 
     716             :     m_aLifeTimeManager.m_aListenerContainer.addInterface(
     717        2146 :         cppu::UnoType<util::XModifyListener>::get(), xListener );
     718             : }
     719             : 
     720         978 : void SAL_CALL ChartModel::removeModifyListener(
     721             :     const uno::Reference< util::XModifyListener >& xListener )
     722             :     throw(uno::RuntimeException, std::exception)
     723             : {
     724         978 :     if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
     725         978 :         return; //behave passive if already disposed or closed
     726             : 
     727             :     m_aLifeTimeManager.m_aListenerContainer.removeInterface(
     728         978 :         cppu::UnoType<util::XModifyListener>::get(), xListener );
     729             : }
     730             : 
     731             : // util::XModifyListener
     732       42043 : void SAL_CALL ChartModel::modified( const lang::EventObject& )
     733             :     throw (uno::RuntimeException, std::exception)
     734             : {
     735       42043 :     if( m_nInLoad == 0 )
     736        9367 :         setModified( sal_True );
     737       42043 : }
     738             : 
     739             : // lang::XEventListener (base of util::XModifyListener)
     740         756 : void SAL_CALL ChartModel::disposing( const lang::EventObject& )
     741             :     throw (uno::RuntimeException, std::exception)
     742             : {
     743             :     // child was disposed -- should not happen from outside
     744         756 : }
     745             : 
     746             : // document::XStorageBasedDocument
     747         232 : void SAL_CALL ChartModel::loadFromStorage(
     748             :     const Reference< embed::XStorage >& xStorage,
     749             :     const Sequence< beans::PropertyValue >& rMediaDescriptor )
     750             :     throw (lang::IllegalArgumentException,
     751             :            frame::DoubleInitializationException,
     752             :            io::IOException,
     753             :            uno::Exception,
     754             :            uno::RuntimeException, std::exception)
     755             : {
     756         232 :     attachResource( OUString(), rMediaDescriptor );
     757         232 :     impl_load( rMediaDescriptor, xStorage );
     758         232 : }
     759             : 
     760         544 : void SAL_CALL ChartModel::storeToStorage(
     761             :     const Reference< embed::XStorage >& xStorage,
     762             :     const Sequence< beans::PropertyValue >& rMediaDescriptor )
     763             :     throw (lang::IllegalArgumentException,
     764             :            io::IOException,
     765             :            uno::Exception,
     766             :            uno::RuntimeException, std::exception)
     767             : {
     768         544 :     impl_store( rMediaDescriptor, xStorage );
     769         544 : }
     770             : 
     771         534 : void SAL_CALL ChartModel::switchToStorage( const Reference< embed::XStorage >& xStorage )
     772             :     throw (lang::IllegalArgumentException,
     773             :            io::IOException,
     774             :            uno::Exception,
     775             :            uno::RuntimeException, std::exception)
     776             : {
     777         534 :     m_xStorage = xStorage;
     778         534 :     impl_notifyStorageChangeListeners();
     779         534 : }
     780             : 
     781         958 : Reference< embed::XStorage > SAL_CALL ChartModel::getDocumentStorage()
     782             :     throw (io::IOException,
     783             :            uno::Exception,
     784             :            uno::RuntimeException, std::exception)
     785             : {
     786         958 :     return m_xStorage;
     787             : }
     788             : 
     789         534 : void SAL_CALL ChartModel::impl_notifyStorageChangeListeners()
     790             :     throw( uno::RuntimeException)
     791             : {
     792             :     ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
     793         534 :           .getContainer( cppu::UnoType<document::XStorageChangeListener>::get());
     794         534 :     if( pIC )
     795             :     {
     796           0 :         ::cppu::OInterfaceIteratorHelper aIt( *pIC );
     797           0 :         while( aIt.hasMoreElements() )
     798             :         {
     799           0 :             uno::Reference< document::XStorageChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
     800           0 :             if( xListener.is() )
     801           0 :                 xListener->notifyStorageChange( static_cast< ::cppu::OWeakObject* >( this ), m_xStorage );
     802           0 :         }
     803             :     }
     804         534 : }
     805             : 
     806           0 : void SAL_CALL ChartModel::addStorageChangeListener( const Reference< document::XStorageChangeListener >& xListener )
     807             :     throw (uno::RuntimeException, std::exception)
     808             : {
     809           0 :     if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
     810           0 :         return; //behave passive if already disposed or closed
     811             : 
     812             :     m_aLifeTimeManager.m_aListenerContainer.addInterface(
     813           0 :         cppu::UnoType<document::XStorageChangeListener>::get(), xListener );
     814             : }
     815             : 
     816           0 : void SAL_CALL ChartModel::removeStorageChangeListener( const Reference< document::XStorageChangeListener >& xListener )
     817             :     throw (uno::RuntimeException, std::exception)
     818             : {
     819           0 :     if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
     820           0 :         return; //behave passive if already disposed or closed
     821             : 
     822             :     m_aLifeTimeManager.m_aListenerContainer.removeInterface(
     823           0 :         cppu::UnoType<document::XStorageChangeListener>::get(), xListener );
     824             : }
     825             : 
     826         108 : } //  namespace chart
     827             : 
     828             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10