LCOV - code coverage report
Current view: top level - chart2/source/model/main - ChartModel_Persistence.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 245 343 71.4 %
Date: 2015-06-13 12:38:46 Functions: 26 35 74.3 %
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        2124 : struct lcl_PropNameEquals : public ::std::unary_function< beans::PropertyValue, bool >
      66             : {
      67         708 :     explicit lcl_PropNameEquals( const OUString & rStrToCompareWith ) :
      68         708 :             m_aStr( rStrToCompareWith )
      69         708 :     {}
      70        4615 :     bool operator() ( const beans::PropertyValue & rProp )
      71             :     {
      72        4615 :         return rProp.Name.equals( m_aStr );
      73             :     }
      74             : private:
      75             :     OUString m_aStr;
      76             : };
      77             : 
      78             : template< typename T >
      79         708 : T lcl_getProperty(
      80             :     const Sequence< beans::PropertyValue > & rMediaDescriptor,
      81             :     const OUString & rPropName )
      82             : {
      83         708 :     T aResult;
      84         708 :     if( rMediaDescriptor.getLength())
      85             :     {
      86         708 :         OUString aPropName( rPropName );
      87         708 :         const beans::PropertyValue * pIt = rMediaDescriptor.getConstArray();
      88         708 :         const beans::PropertyValue * pEndIt = pIt +  + rMediaDescriptor.getLength();
      89         708 :         pIt = ::std::find_if( pIt, pEndIt, lcl_PropNameEquals( aPropName ));
      90         708 :         if( pIt != pEndIt )
      91         708 :             (*pIt).Value >>= aResult;
      92             :     }
      93         708 :     return aResult;
      94             : }
      95             : 
      96         354 : void lcl_addStorageToMediaDescriptor(
      97             :     Sequence< beans::PropertyValue > & rOutMD,
      98             :     const Reference< embed::XStorage > & xStorage )
      99             : {
     100         354 :     rOutMD.realloc( rOutMD.getLength() + 1 );
     101         708 :     rOutMD[rOutMD.getLength() - 1] = beans::PropertyValue(
     102         354 :         "Storage", -1, uno::makeAny( xStorage ), beans::PropertyState_DIRECT_VALUE );
     103         354 : }
     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         354 : Reference< document::XFilter > ChartModel::impl_createFilter(
     148             :     const Sequence< beans::PropertyValue > & rMediaDescriptor )
     149             : {
     150         354 :     Reference< document::XFilter > xFilter;
     151             : 
     152             :     // find FilterName in MediaDescriptor
     153             :     OUString aFilterName(
     154         708 :         lcl_getProperty< OUString >( rMediaDescriptor, "FilterName" ) );
     155             : 
     156             :     // if FilterName was found, get Filter from factory
     157         354 :     if( !aFilterName.isEmpty() )
     158             :     {
     159             :         try
     160             :         {
     161             :             Reference< container::XNameAccess > xFilterFact(
     162         708 :                 m_xContext->getServiceManager()->createInstanceWithContext(
     163         354 :                     "com.sun.star.document.FilterFactory", m_xContext ),
     164         354 :                 uno::UNO_QUERY_THROW );
     165         708 :             uno::Any aFilterProps( xFilterFact->getByName( aFilterName ));
     166         708 :             Sequence< beans::PropertyValue > aProps;
     167             : 
     168         708 :             if( aFilterProps.hasValue() &&
     169         354 :                 (aFilterProps >>= aProps))
     170             :             {
     171             :                 OUString aFilterServiceName(
     172         354 :                     lcl_getProperty< OUString >( aProps, "FilterService" ) );
     173             : 
     174         354 :                 if( !aFilterServiceName.isEmpty())
     175             :                 {
     176             :                     xFilter.set(
     177         708 :                         m_xContext->getServiceManager()->createInstanceWithContext(
     178         354 :                             aFilterServiceName, m_xContext ), uno::UNO_QUERY_THROW );
     179             :                     SAL_INFO("chart2", "Filter found for service " << aFilterServiceName );
     180         354 :                 }
     181         354 :             }
     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         354 :     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         708 :     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         820 : sal_Bool SAL_CALL ChartModel::isReadonly()
     232             :     throw(uno::RuntimeException, std::exception)
     233             : {
     234             :     //@todo guard
     235         820 :     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         269 : void ChartModel::impl_store(
     341             :     const Sequence< beans::PropertyValue >& rMediaDescriptor,
     342             :     const Reference< embed::XStorage > & xStorage )
     343             : {
     344         269 :     Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor));
     345         269 :     if( xFilter.is() && xStorage.is())
     346             :     {
     347         269 :         Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
     348         269 :         lcl_addStorageToMediaDescriptor( aMD, xStorage );
     349             :         try
     350             :         {
     351         269 :             Reference< document::XExporter > xExporter( xFilter, uno::UNO_QUERY_THROW );
     352         269 :             xExporter->setSourceDocument( Reference< lang::XComponent >( this ));
     353         269 :             xFilter->filter( aMD );
     354             :         }
     355           0 :         catch( const uno::Exception & ex )
     356             :         {
     357             :             ASSERT_EXCEPTION( ex );
     358         269 :         }
     359             :     }
     360             :     else
     361             :     {
     362             :         OSL_FAIL( "No filter" );
     363             :     }
     364             : 
     365         269 :     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         538 :     Reference< beans::XPropertySet > xPropSet( m_xParent, uno::UNO_QUERY );
     372         269 :     if ( !hasInternalDataProvider() && xPropSet.is() )
     373             :     {
     374           6 :         apphelper::MediaDescriptorHelper aMDHelper(rMediaDescriptor);
     375             :         try
     376             :         {
     377           6 :             xPropSet->setPropertyValue(
     378             :                 "SavedObject",
     379           7 :                 uno::makeAny( aMDHelper.HierarchicalDocumentName ) );
     380             :         }
     381           1 :         catch ( const uno::Exception& )
     382             :         {
     383           6 :         }
     384         269 :     }
     385         269 : }
     386             : 
     387          14 : void ChartModel::insertDefaultChart()
     388             : {
     389          14 :     lockControllers();
     390          14 :     createInternalDataProvider( sal_False );
     391             :     try
     392             :     {
     393             :         // create default chart
     394          14 :         Reference< chart2::XChartTypeTemplate > xTemplate( impl_createDefaultChartTypeTemplate() );
     395          14 :         if( xTemplate.is())
     396             :         {
     397             :             try
     398             :             {
     399          14 :                 Reference< chart2::data::XDataSource > xDataSource( impl_createDefaultData() );
     400          28 :                 Sequence< beans::PropertyValue > aParam;
     401             : 
     402          14 :                 bool bSupportsCategories = xTemplate->supportsCategories();
     403          14 :                 if( bSupportsCategories )
     404             :                 {
     405          14 :                     aParam.realloc( 1 );
     406          28 :                     aParam[0] = beans::PropertyValue( "HasCategories", -1, uno::makeAny( true ),
     407          14 :                                                       beans::PropertyState_DIRECT_VALUE );
     408             :                 }
     409             : 
     410          28 :                 Reference< chart2::XDiagram > xDiagram( xTemplate->createDiagramByDataSource( xDataSource, aParam ) );
     411             : 
     412          14 :                 setFirstDiagram( xDiagram );
     413             : 
     414          14 :                 bool bIsRTL = AllSettings::GetMathLayoutRTL();
     415             :                 //reverse x axis for rtl charts
     416          14 :                 if( bIsRTL )
     417           0 :                     AxisHelper::setRTLAxisLayout( AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 ) );
     418             : 
     419             :                 // create and attach legend
     420             :                 Reference< chart2::XLegend > xLegend(
     421          28 :                     m_xContext->getServiceManager()->createInstanceWithContext(
     422          28 :                         "com.sun.star.chart2.Legend", m_xContext ), uno::UNO_QUERY_THROW );
     423          28 :                 Reference< beans::XPropertySet > xLegendProperties( xLegend, uno::UNO_QUERY );
     424          14 :                 if( xLegendProperties.is() )
     425             :                 {
     426          14 :                     xLegendProperties->setPropertyValue( "FillStyle", uno::makeAny( drawing::FillStyle_NONE ));
     427          14 :                     xLegendProperties->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_NONE ));
     428          14 :                     xLegendProperties->setPropertyValue( "LineColor", uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ));  // gray30
     429          14 :                     xLegendProperties->setPropertyValue( "FillColor", uno::makeAny( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10
     430             : 
     431          14 :                     if( bIsRTL )
     432           0 :                         xLegendProperties->setPropertyValue( "AnchorPosition", uno::makeAny( chart2::LegendPosition_LINE_START ));
     433             :                 }
     434          14 :                 if(xDiagram.is())
     435          14 :                     xDiagram->setLegend( xLegend );
     436             : 
     437             :                 // set simple 3D look
     438          28 :                 Reference< beans::XPropertySet > xDiagramProperties( xDiagram, uno::UNO_QUERY );
     439          14 :                 if( xDiagramProperties.is() )
     440             :                 {
     441          14 :                     xDiagramProperties->setPropertyValue( "RightAngledAxes", uno::makeAny( sal_True ));
     442          14 :                     xDiagramProperties->setPropertyValue( "D3DScenePerspective", uno::makeAny( drawing::ProjectionMode_PARALLEL ));
     443          14 :                     ThreeDHelper::setScheme( xDiagram, ThreeDLookScheme_Realistic );
     444             :                 }
     445             : 
     446             :                 //set some new 'defaults' for wall and floor
     447          14 :                 if( xDiagram.is() )
     448             :                 {
     449          14 :                     Reference< beans::XPropertySet > xWall( xDiagram->getWall() );
     450          14 :                     if( xWall.is() )
     451             :                     {
     452          14 :                         xWall->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_SOLID ) );
     453          14 :                         xWall->setPropertyValue( "FillStyle", uno::makeAny( drawing::FillStyle_NONE ) );
     454          14 :                         xWall->setPropertyValue( "LineColor", uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30
     455          14 :                         xWall->setPropertyValue( "FillColor", uno::makeAny( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10
     456             :                     }
     457          28 :                     Reference< beans::XPropertySet > xFloor( xDiagram->getFloor() );
     458          14 :                     if( xFloor.is() )
     459             :                     {
     460          14 :                         xFloor->setPropertyValue( "LineStyle", uno::makeAny( drawing::LineStyle_NONE ) );
     461          14 :                         xFloor->setPropertyValue( "FillStyle", uno::makeAny( drawing::FillStyle_SOLID ) );
     462          14 :                         xFloor->setPropertyValue( "LineColor", uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30
     463          14 :                         xFloor->setPropertyValue( "FillColor", uno::makeAny( static_cast< sal_Int32 >( 0xcccccc ) ) ); // gray20
     464          14 :                     }
     465             : 
     466          14 :                 }
     467             :             }
     468           0 :             catch( const uno::Exception & ex )
     469             :             {
     470             :                 ASSERT_EXCEPTION( ex );
     471             :             }
     472             :         }
     473          14 :         ChartModelHelper::setIncludeHiddenCells( false, *this );
     474             :     }
     475           0 :     catch( const uno::Exception & ex )
     476             :     {
     477             :         ASSERT_EXCEPTION( ex );
     478             :     }
     479          14 :     setModified( sal_False );
     480          14 :     unlockControllers();
     481          14 : }
     482             : 
     483             : // frame::XLoadable
     484         235 : void SAL_CALL ChartModel::initNew()
     485             :     throw (frame::DoubleInitializationException,
     486             :            io::IOException,
     487             :            uno::Exception,
     488             :            uno::RuntimeException, std::exception)
     489             : {
     490         235 : }
     491             : 
     492           5 : 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           5 :     Reference< embed::XStorage > xStorage;
     500          10 :     OUString aURL;
     501             :     try
     502             :     {
     503           5 :         apphelper::MediaDescriptorHelper aMDHelper( rMediaDescriptor );
     504           5 :         if( aMDHelper.ISSET_Storage )
     505             :         {
     506           0 :             xStorage = aMDHelper.Storage;
     507             :         }
     508           5 :         else if( aMDHelper.ISSET_Stream ||
     509             :                  aMDHelper.ISSET_InputStream )
     510             :         {
     511          10 :             if( aMDHelper.ISSET_FilterName &&
     512          10 :                 (aMDHelper.FilterName == "StarChart 5.0" ||
     513          10 :                  aMDHelper.FilterName == "StarChart 4.0" ||
     514           5 :                  aMDHelper.FilterName == "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           5 :                 return;
     520             :             }
     521             : 
     522           5 :             Reference< lang::XSingleServiceFactory > xStorageFact( embed::StorageFactory::create(m_xContext) );
     523             : 
     524           5 :             if( aMDHelper.ISSET_Stream )
     525             :             {
     526             :                 // convert XStream to XStorage via the storage factory
     527           3 :                 Sequence< uno::Any > aStorageArgs( 2 );
     528           3 :                 aStorageArgs[0] <<= aMDHelper.Stream;
     529             :                 // todo: check if stream is read-only
     530           3 :                 aStorageArgs[1] <<= (embed::ElementModes::READ); //WRITE | embed::ElementModes::NOCREATE);
     531             : 
     532           3 :                 xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
     533           3 :                     uno::UNO_QUERY_THROW );
     534             :             }
     535             :             else
     536             :             {
     537             :                 OSL_ASSERT( aMDHelper.ISSET_InputStream );
     538             :                 // convert XInputStream to XStorage via the storage factory
     539           2 :                 Sequence< uno::Any > aStorageArgs( 2 );
     540           2 :                 aStorageArgs[0] <<= aMDHelper.InputStream;
     541           2 :                 aStorageArgs[1] <<= (embed::ElementModes::READ);
     542             : 
     543           2 :                 xStorage.set( xStorageFact->createInstanceWithArguments( aStorageArgs ),
     544           2 :                     uno::UNO_QUERY_THROW );
     545           5 :             }
     546             :         }
     547             : 
     548           5 :         if( aMDHelper.ISSET_URL )
     549           5 :             aURL = aMDHelper.URL;
     550             :     }
     551           0 :     catch( const uno::Exception & ex )
     552             :     {
     553             :         ASSERT_EXCEPTION( ex );
     554             :     }
     555             : 
     556           5 :     if( xStorage.is())
     557             :     {
     558           5 :         attachResource( aURL, rMediaDescriptor );
     559           5 :         impl_load( rMediaDescriptor, xStorage );
     560           5 :     }
     561             : }
     562             : 
     563          85 : void ChartModel::impl_load(
     564             :     const Sequence< beans::PropertyValue >& rMediaDescriptor,
     565             :     const Reference< embed::XStorage >& xStorage )
     566             : {
     567             :     {
     568          85 :         MutexGuard aGuard( m_aModelMutex );
     569          85 :         m_nInLoad++;
     570             :     }
     571             : 
     572          85 :     Reference< document::XFilter > xFilter( impl_createFilter( rMediaDescriptor ));
     573             : 
     574          85 :     if( xFilter.is())
     575             :     {
     576          85 :         Reference< document::XImporter > xImporter( xFilter, uno::UNO_QUERY_THROW );
     577          85 :         xImporter->setTargetDocument( this );
     578         170 :         Sequence< beans::PropertyValue > aMD( rMediaDescriptor );
     579          85 :         lcl_addStorageToMediaDescriptor( aMD, xStorage );
     580             : 
     581          85 :         xFilter->filter( aMD );
     582         170 :         xFilter.clear();
     583             :     }
     584             :     else
     585             :     {
     586             :         OSL_FAIL( "loadFromStorage cannot create filter" );
     587             :     }
     588             : 
     589          85 :     if( xStorage.is() )
     590          85 :         impl_loadGraphics( xStorage );
     591             : 
     592          85 :     setModified( sal_False );
     593             : 
     594             :     // switchToStorage without notifying listeners (which shouldn't exist at
     595             :     // this time, anyway)
     596          85 :     m_xStorage = xStorage;
     597             : 
     598             :     {
     599          85 :         MutexGuard aGuard( m_aModelMutex );
     600          85 :         m_nInLoad--;
     601          85 :     }
     602          85 : }
     603             : 
     604          85 : void ChartModel::impl_loadGraphics(
     605             :     const Reference< embed::XStorage >& xStorage )
     606             : {
     607             :     try
     608             :     {
     609             :         const Reference< embed::XStorage >& xGraphicsStorage(
     610          85 :             xStorage->openStorageElement( "Pictures",
     611         162 :                                           embed::ElementModes::READ ) );
     612             : 
     613           8 :         if( xGraphicsStorage.is() )
     614             :         {
     615             :             const uno::Sequence< OUString > aElementNames(
     616           8 :                 xGraphicsStorage->getElementNames() );
     617             : 
     618          19 :             for( int i = 0; i < aElementNames.getLength(); ++i )
     619             :             {
     620          11 :                 if( xGraphicsStorage->isStreamElement( aElementNames[ i ] ) )
     621             :                 {
     622             :                     uno::Reference< io::XStream > xElementStream(
     623          11 :                         xGraphicsStorage->openStreamElement(
     624          11 :                             aElementNames[ i ],
     625          22 :                             embed::ElementModes::READ ) );
     626             : 
     627          11 :                     if( xElementStream.is() )
     628             :                     {
     629             :                         boost::scoped_ptr< SvStream > apIStm(
     630             :                             ::utl::UcbStreamHelper::CreateStream(
     631          11 :                                 xElementStream, true ) );
     632             : 
     633          11 :                         if( apIStm.get() )
     634             :                         {
     635          11 :                             Graphic aGraphic;
     636             : 
     637          11 :                             if( !GraphicConverter::Import(
     638          11 :                                     *apIStm.get(),
     639          11 :                                     aGraphic ) )
     640             :                             {
     641          11 :                                 m_aGraphicObjectVector.push_back( aGraphic );
     642          11 :                             }
     643          11 :                         }
     644          11 :                     }
     645             :                 }
     646           8 :             }
     647           8 :         }
     648             :     }
     649          77 :     catch ( const uno::Exception& )
     650             :     {
     651             :     }
     652          85 : }
     653             : 
     654             : // util::XModifiable
     655        1770 : void SAL_CALL ChartModel::impl_notifyModifiedListeners()
     656             :     throw( uno::RuntimeException)
     657             : {
     658             :     {
     659        1770 :         MutexGuard aGuard( m_aModelMutex );
     660        1770 :         m_bUpdateNotificationsPending = false;
     661             :     }
     662             : 
     663             :     //always notify the view first!
     664        1770 :     ChartViewHelper::setViewToDirtyState( this );
     665             : 
     666             :     ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
     667        1770 :         .getContainer( cppu::UnoType<util::XModifyListener>::get());
     668        1770 :     if( pIC )
     669             :     {
     670        1626 :         lang::EventObject aEvent( static_cast< lang::XComponent*>(this) );
     671        3252 :         ::cppu::OInterfaceIteratorHelper aIt( *pIC );
     672        8860 :         while( aIt.hasMoreElements() )
     673             :         {
     674        5608 :             uno::Reference< util::XModifyListener > xListener( aIt.next(), uno::UNO_QUERY );
     675        5608 :             if( xListener.is() )
     676        5608 :                 xListener->modified( aEvent );
     677        7234 :         }
     678             :     }
     679        1770 : }
     680             : 
     681        2370 : sal_Bool SAL_CALL ChartModel::isModified()
     682             :     throw(uno::RuntimeException, std::exception)
     683             : {
     684             :     //@todo guard
     685        2370 :     return m_bModified;
     686             : }
     687             : 
     688        8110 : void SAL_CALL ChartModel::setModified( sal_Bool bModified )
     689             :     throw(beans::PropertyVetoException,
     690             :           uno::RuntimeException, std::exception)
     691             : {
     692        8110 :     apphelper::LifeTimeGuard aGuard(m_aLifeTimeManager);
     693        8110 :     if(!aGuard.startApiCall())//@todo ? is this a long lasting call??
     694           0 :         return; //behave passive if already disposed or closed or throw exception @todo?
     695        8110 :     m_bModified = bModified;
     696             : 
     697        8110 :     if( m_nControllerLockCount > 0 )
     698             :     {
     699        6005 :         m_bUpdateNotificationsPending = true;
     700        6005 :         return;//don't call listeners if controllers are locked
     701             :     }
     702        2105 :     aGuard.clear();
     703             : 
     704        2105 :     if(bModified)
     705        1124 :         impl_notifyModifiedListeners();
     706             : }
     707             : 
     708             : // util::XModifyBroadcaster (base of XModifiable)
     709        1165 : void SAL_CALL ChartModel::addModifyListener(
     710             :     const uno::Reference< util::XModifyListener >& xListener )
     711             :     throw(uno::RuntimeException, std::exception)
     712             : {
     713        1165 :     if( m_aLifeTimeManager.impl_isDisposedOrClosed() )
     714        1165 :         return; //behave passive if already disposed or closed
     715             : 
     716             :     m_aLifeTimeManager.m_aListenerContainer.addInterface(
     717        1165 :         cppu::UnoType<util::XModifyListener>::get(), xListener );
     718             : }
     719             : 
     720         564 : void SAL_CALL ChartModel::removeModifyListener(
     721             :     const uno::Reference< util::XModifyListener >& xListener )
     722             :     throw(uno::RuntimeException, std::exception)
     723             : {
     724         564 :     if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) )
     725         564 :         return; //behave passive if already disposed or closed
     726             : 
     727             :     m_aLifeTimeManager.m_aListenerContainer.removeInterface(
     728         564 :         cppu::UnoType<util::XModifyListener>::get(), xListener );
     729             : }
     730             : 
     731             : // util::XModifyListener
     732       15912 : void SAL_CALL ChartModel::modified( const lang::EventObject& )
     733             :     throw (uno::RuntimeException, std::exception)
     734             : {
     735       15912 :     if( m_nInLoad == 0 )
     736        5660 :         setModified( sal_True );
     737       15912 : }
     738             : 
     739             : // lang::XEventListener (base of util::XModifyListener)
     740         454 : 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         454 : }
     745             : 
     746             : // document::XStorageBasedDocument
     747          80 : 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          80 :     attachResource( OUString(), rMediaDescriptor );
     757          80 :     impl_load( rMediaDescriptor, xStorage );
     758          80 : }
     759             : 
     760         269 : 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         269 :     impl_store( rMediaDescriptor, xStorage );
     769         269 : }
     770             : 
     771         264 : 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         264 :     m_xStorage = xStorage;
     778         264 :     impl_notifyStorageChangeListeners();
     779         264 : }
     780             : 
     781         335 : Reference< embed::XStorage > SAL_CALL ChartModel::getDocumentStorage()
     782             :     throw (io::IOException,
     783             :            uno::Exception,
     784             :            uno::RuntimeException, std::exception)
     785             : {
     786         335 :     return m_xStorage;
     787             : }
     788             : 
     789         264 : void SAL_CALL ChartModel::impl_notifyStorageChangeListeners()
     790             :     throw( uno::RuntimeException)
     791             : {
     792             :     ::cppu::OInterfaceContainerHelper* pIC = m_aLifeTimeManager.m_aListenerContainer
     793         264 :           .getContainer( cppu::UnoType<document::XStorageChangeListener>::get());
     794         264 :     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         264 : }
     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             : } //  namespace chart
     827             : 
     828             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11