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

Generated by: LCOV version 1.10