| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_chart2.hxx" |
| |
| #include "DialogModel.hxx" |
| #include "RangeSelectionHelper.hxx" |
| #include "PropertyHelper.hxx" |
| #include "DataSeriesHelper.hxx" |
| #include "DataSourceHelper.hxx" |
| #include "DiagramHelper.hxx" |
| #include "macros.hxx" |
| #include "Strings.hrc" |
| #include "ResId.hxx" |
| #include "ContainerHelper.hxx" |
| #include "CommonFunctors.hxx" |
| #include "ControllerLockGuard.hxx" |
| #include "ChartTypeHelper.hxx" |
| #include "ThreeDHelper.hxx" |
| |
| #include <com/sun/star/util/XCloneable.hpp> |
| #include <com/sun/star/chart2/AxisType.hpp> |
| #include <com/sun/star/chart2/XTitled.hpp> |
| #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> |
| #include <com/sun/star/chart2/XChartTypeContainer.hpp> |
| #include <com/sun/star/chart2/XDataSeriesContainer.hpp> |
| #include <com/sun/star/chart2/data/XDataSink.hpp> |
| |
| #include <tools/string.hxx> |
| |
| #include <utility> |
| #include <algorithm> |
| #include <iterator> |
| #include <functional> |
| #include <numeric> |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::chart2; |
| using namespace ::chart::ContainerHelper; |
| |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::uno::Sequence; |
| using ::rtl::OUString; |
| |
| // ---------------------------------------- |
| |
| namespace |
| { |
| const OUString lcl_aLabelRole( RTL_CONSTASCII_USTRINGPARAM( "label" )); |
| |
| struct lcl_ChartTypeToSeriesCnt : ::std::unary_function< |
| Reference< XChartType >, Reference< XDataSeriesContainer > > |
| { |
| Reference< XDataSeriesContainer > operator() ( |
| const Reference< XChartType > & xChartType ) |
| { |
| return Reference< XDataSeriesContainer >::query( xChartType ); |
| } |
| }; |
| |
| OUString lcl_ConvertRole( const OUString & rRoleString, bool bFromInternalToUI ) |
| { |
| OUString aResult( rRoleString ); |
| |
| typedef ::std::map< OUString, OUString > tTranslationMap; |
| static tTranslationMap aTranslationMap; |
| |
| if( aTranslationMap.size() == 0 ) |
| { |
| aTranslationMap[ C2U( "categories" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_CATEGORIES ))); |
| aTranslationMap[ C2U( "error-bars-x" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR ))); |
| aTranslationMap[ C2U( "error-bars-x-positive" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR_POSITIVE ))); |
| aTranslationMap[ C2U( "error-bars-x-negative" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X_ERROR_NEGATIVE ))); |
| aTranslationMap[ C2U( "error-bars-y" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR ))); |
| aTranslationMap[ C2U( "error-bars-y-positive" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_POSITIVE ))); |
| aTranslationMap[ C2U( "error-bars-y-negative" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y_ERROR_NEGATIVE ))); |
| aTranslationMap[ C2U( "label" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_LABEL ))); |
| aTranslationMap[ C2U( "values-first" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_FIRST ))); |
| aTranslationMap[ C2U( "values-last" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_LAST ))); |
| aTranslationMap[ C2U( "values-max" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_MAX ))); |
| aTranslationMap[ C2U( "values-min" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_MIN ))); |
| aTranslationMap[ C2U( "values-x" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_X ))); |
| aTranslationMap[ C2U( "values-y" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_Y ))); |
| aTranslationMap[ C2U( "values-size" ) ] = OUString( String( ::chart::SchResId( STR_DATA_ROLE_SIZE ))); |
| } |
| |
| if( bFromInternalToUI ) |
| { |
| tTranslationMap::const_iterator aIt( aTranslationMap.find( rRoleString )); |
| if( aIt != aTranslationMap.end()) |
| { |
| aResult = (*aIt).second; |
| } |
| } |
| else |
| { |
| tTranslationMap::const_iterator aIt( |
| ::std::find_if( aTranslationMap.begin(), aTranslationMap.end(), |
| ::std::compose1( ::std::bind2nd( |
| ::std::equal_to< tTranslationMap::mapped_type >(), |
| rRoleString ), |
| ::std::select2nd< tTranslationMap::value_type >()))); |
| |
| if( aIt != aTranslationMap.end()) |
| aResult = (*aIt).first; |
| } |
| |
| return aResult; |
| } |
| |
| typedef ::std::map< ::rtl::OUString, sal_Int32 > lcl_tRoleIndexMap; |
| |
| void lcl_createRoleIndexMap( lcl_tRoleIndexMap & rOutMap ) |
| { |
| rOutMap.clear(); |
| sal_Int32 nIndex = 0; |
| |
| rOutMap[ C2U( "label" ) ] = ++nIndex; |
| rOutMap[ C2U( "categories" ) ] = ++nIndex; |
| rOutMap[ C2U( "values-x" ) ] = ++nIndex; |
| rOutMap[ C2U( "values-y" ) ] = ++nIndex; |
| rOutMap[ C2U( "error-bars-x" ) ] = ++nIndex; |
| rOutMap[ C2U( "error-bars-x-positive" ) ] = ++nIndex; |
| rOutMap[ C2U( "error-bars-x-negative" ) ] = ++nIndex; |
| rOutMap[ C2U( "error-bars-y" ) ] = ++nIndex; |
| rOutMap[ C2U( "error-bars-y-positive" ) ] = ++nIndex; |
| rOutMap[ C2U( "error-bars-y-negative" ) ] = ++nIndex; |
| rOutMap[ C2U( "values-first" ) ] = ++nIndex; |
| rOutMap[ C2U( "values-min" ) ] = ++nIndex; |
| rOutMap[ C2U( "values-max" ) ] = ++nIndex; |
| rOutMap[ C2U( "values-last" ) ] = ++nIndex; |
| rOutMap[ C2U( "values-size" ) ] = ++nIndex; |
| } |
| |
| struct lcl_DataSeriesContainerAppend : public |
| ::std::iterator< ::std::output_iterator_tag, Reference< XDataSeriesContainer > > |
| { |
| typedef ::std::vector< ::chart::DialogModel::tSeriesWithChartTypeByName > tContainerType; |
| |
| explicit lcl_DataSeriesContainerAppend( tContainerType & rCnt ) |
| : m_rDestCnt( rCnt ) |
| {} |
| |
| lcl_DataSeriesContainerAppend & operator= ( const value_type & xVal ) |
| { |
| try |
| { |
| if( xVal.is()) |
| { |
| Sequence< Reference< XDataSeries > > aSeq( xVal->getDataSeries()); |
| OUString aRole( RTL_CONSTASCII_USTRINGPARAM("values-y")); |
| Reference< XChartType > xCT( xVal, uno::UNO_QUERY ); |
| if( xCT.is()) |
| aRole = xCT->getRoleOfSequenceForSeriesLabel(); |
| for( sal_Int32 nI = 0; nI < aSeq.getLength(); ++ nI ) |
| { |
| m_rDestCnt.push_back( |
| ::chart::DialogModel::tSeriesWithChartTypeByName( |
| ::chart::DataSeriesHelper::getDataSeriesLabel( aSeq[nI], aRole ), |
| ::std::make_pair( aSeq[nI], xCT ))); |
| } |
| } |
| } |
| catch( uno::Exception & ex ) |
| { |
| ASSERT_EXCEPTION( ex ); |
| } |
| return *this; |
| } |
| |
| lcl_DataSeriesContainerAppend & operator* () { return *this; } |
| lcl_DataSeriesContainerAppend & operator++ () { return *this; } |
| lcl_DataSeriesContainerAppend & operator++ (int) { return *this; } |
| |
| private: |
| tContainerType & m_rDestCnt; |
| }; |
| |
| struct lcl_RolesWithRangeAppend : public |
| ::std::iterator< ::std::output_iterator_tag, Reference< data::XLabeledDataSequence > > |
| { |
| typedef ::chart::DialogModel::tRolesWithRanges tContainerType; |
| |
| explicit lcl_RolesWithRangeAppend( tContainerType & rCnt, |
| const ::rtl::OUString & aLabelRole ) |
| : m_rDestCnt( rCnt ), |
| m_aRoleForLabelSeq( aLabelRole ) |
| {} |
| |
| lcl_RolesWithRangeAppend & operator= ( const value_type & xVal ) |
| { |
| try |
| { |
| if( xVal.is()) |
| { |
| // data sequence |
| Reference< data::XDataSequence > xSeq( xVal->getValues()); |
| if( xSeq.is()) |
| { |
| OUString aRole; |
| Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY_THROW ); |
| if( xProp->getPropertyValue( C2U("Role")) >>= aRole ) |
| { |
| m_rDestCnt.insert( |
| tContainerType::value_type( |
| aRole, xSeq->getSourceRangeRepresentation())); |
| // label |
| if( aRole.equals( m_aRoleForLabelSeq )) |
| { |
| Reference< data::XDataSequence > xLabelSeq( xVal->getLabel()); |
| if( xLabelSeq.is()) |
| { |
| m_rDestCnt.insert( |
| tContainerType::value_type( |
| lcl_aLabelRole, xLabelSeq->getSourceRangeRepresentation())); |
| } |
| } |
| } |
| } |
| } |
| } |
| catch( uno::Exception & ex ) |
| { |
| ASSERT_EXCEPTION( ex ); |
| } |
| return *this; |
| } |
| |
| lcl_RolesWithRangeAppend & operator* () { return *this; } |
| lcl_RolesWithRangeAppend & operator++ () { return *this; } |
| lcl_RolesWithRangeAppend & operator++ (int) { return *this; } |
| |
| private: |
| tContainerType & m_rDestCnt; |
| OUString m_aRoleForLabelSeq; |
| }; |
| |
| void lcl_SetSequenceRole( |
| const Reference< data::XDataSequence > & xSeq, |
| const OUString & rRole ) |
| { |
| Reference< beans::XPropertySet > xProp( xSeq, uno::UNO_QUERY ); |
| if( xProp.is()) |
| xProp->setPropertyValue( C2U("Role"), uno::makeAny( rRole )); |
| } |
| |
| Reference< XDataSeries > lcl_CreateNewSeries( |
| const Reference< uno::XComponentContext > & xContext, |
| const Reference< XChartType > & xChartType, |
| sal_Int32 nNewSeriesIndex, |
| sal_Int32 nTotalNumberOfSeriesInCTGroup, |
| const Reference< XDiagram > & xDiagram, |
| const Reference< XChartTypeTemplate > & xTemplate, |
| bool bCreateDataCachedSequences ) |
| { |
| // create plain series |
| Reference< XDataSeries > xResult( |
| xContext->getServiceManager()->createInstanceWithContext( |
| C2U( "com.sun.star.chart2.DataSeries" ), |
| xContext ), uno::UNO_QUERY ); |
| if( xTemplate.is()) |
| { |
| Reference< beans::XPropertySet > xResultProp( xResult, uno::UNO_QUERY ); |
| if( xResultProp.is()) |
| { |
| // @deprecated: correct default color should be found by view |
| // without setting it as hard attribute |
| Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme()); |
| if( xColorScheme.is()) |
| xResultProp->setPropertyValue( |
| C2U("Color"), uno::makeAny( xColorScheme->getColorByIndex( nNewSeriesIndex ))); |
| } |
| sal_Int32 nGroupIndex=0; |
| if( xChartType.is()) |
| { |
| Sequence< Reference< XChartType > > aCTs( |
| ::chart::DiagramHelper::getChartTypesFromDiagram( xDiagram )); |
| for( ; nGroupIndex<aCTs.getLength(); ++nGroupIndex) |
| if( aCTs[nGroupIndex] == xChartType ) |
| break; |
| if( nGroupIndex == aCTs.getLength()) |
| nGroupIndex = 0; |
| } |
| xTemplate->applyStyle( xResult, nGroupIndex, nNewSeriesIndex, nTotalNumberOfSeriesInCTGroup ); |
| } |
| |
| if( bCreateDataCachedSequences ) |
| { |
| // set chart type specific roles |
| Reference< data::XDataSink > xSink( xResult, uno::UNO_QUERY ); |
| if( xChartType.is() && xSink.is()) |
| { |
| ::std::vector< Reference< data::XLabeledDataSequence > > aNewSequences; |
| const OUString aRoleOfSeqForSeriesLabel = xChartType->getRoleOfSequenceForSeriesLabel(); |
| const OUString aLabel( String( ::chart::SchResId( STR_DATA_UNNAMED_SERIES ))); |
| const Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles()); |
| const Sequence< OUString > aOptRoles( xChartType->getSupportedOptionalRoles()); |
| sal_Int32 nI = 0; |
| |
| for(nI=0; nI<aRoles.getLength(); ++nI) |
| { |
| if( aRoles[nI].equals( lcl_aLabelRole )) |
| continue; |
| Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence() ); |
| lcl_SetSequenceRole( xSeq, aRoles[nI] ); |
| // assert that aRoleOfSeqForSeriesLabel is part of the mandatory roles |
| if( aRoles[nI].equals( aRoleOfSeqForSeriesLabel )) |
| { |
| Reference< data::XDataSequence > xLabel( ::chart::DataSourceHelper::createCachedDataSequence( aLabel )); |
| lcl_SetSequenceRole( xLabel, lcl_aLabelRole ); |
| aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq, xLabel )); |
| } |
| else |
| aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq )); |
| } |
| |
| for(nI=0; nI<aOptRoles.getLength(); ++nI) |
| { |
| if( aOptRoles[nI].equals( lcl_aLabelRole )) |
| continue; |
| Reference< data::XDataSequence > xSeq( ::chart::DataSourceHelper::createCachedDataSequence()); |
| lcl_SetSequenceRole( xSeq, aOptRoles[nI] ); |
| aNewSequences.push_back( ::chart::DataSourceHelper::createLabeledDataSequence( xSeq )); |
| } |
| |
| xSink->setData( ContainerToSequence( aNewSequences )); |
| } |
| } |
| |
| return xResult; |
| } |
| |
| struct lcl_addSeriesNumber : public ::std::binary_function< |
| sal_Int32, Reference< XDataSeriesContainer >, sal_Int32 > |
| { |
| sal_Int32 operator() ( sal_Int32 nCurrentNumber, const Reference< XDataSeriesContainer > & xCnt ) const |
| { |
| if( xCnt.is()) |
| return nCurrentNumber + (xCnt->getDataSeries().getLength()); |
| return nCurrentNumber; |
| } |
| }; |
| |
| } // anonymous namespace |
| |
| // ---------------------------------------- |
| |
| |
| namespace chart |
| { |
| |
| DialogModel::DialogModel( |
| const Reference< XChartDocument > & xChartDocument, |
| const Reference< uno::XComponentContext > & xContext ) : |
| m_xChartDocument( xChartDocument ), |
| m_xContext( xContext ), |
| m_aTimerTriggeredControllerLock( uno::Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) ) |
| { |
| } |
| |
| DialogModel::~DialogModel() |
| {} |
| |
| void DialogModel::setTemplate( |
| const Reference< XChartTypeTemplate > & xTemplate ) |
| { |
| m_xTemplate = xTemplate; |
| } |
| |
| ::boost::shared_ptr< RangeSelectionHelper > |
| DialogModel::getRangeSelectionHelper() const |
| { |
| if( ! m_spRangeSelectionHelper.get()) |
| m_spRangeSelectionHelper.reset( |
| new RangeSelectionHelper( m_xChartDocument )); |
| |
| return m_spRangeSelectionHelper; |
| } |
| |
| Reference< frame::XModel > DialogModel::getChartModel() const |
| { |
| Reference< frame::XModel > xResult( m_xChartDocument, uno::UNO_QUERY ); |
| return xResult; |
| } |
| |
| Reference< data::XDataProvider > DialogModel::getDataProvider() const |
| { |
| Reference< data::XDataProvider > xResult; |
| if( m_xChartDocument.is()) |
| xResult.set( m_xChartDocument->getDataProvider()); |
| return xResult; |
| } |
| |
| ::std::vector< Reference< XDataSeriesContainer > > |
| DialogModel::getAllDataSeriesContainers() const |
| { |
| ::std::vector< Reference< XDataSeriesContainer > > aResult; |
| |
| try |
| { |
| Reference< XDiagram > xDiagram; |
| if( m_xChartDocument.is()) |
| xDiagram.set( m_xChartDocument->getFirstDiagram()); |
| if( xDiagram.is()) |
| { |
| Reference< XCoordinateSystemContainer > xCooSysCnt( |
| xDiagram, uno::UNO_QUERY_THROW ); |
| Sequence< Reference< XCoordinateSystem > > aCooSysSeq( |
| xCooSysCnt->getCoordinateSystems()); |
| for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i ) |
| { |
| Reference< XChartTypeContainer > xCTCnt( aCooSysSeq[i], uno::UNO_QUERY_THROW ); |
| Sequence< Reference< XChartType > > aChartTypeSeq( xCTCnt->getChartTypes()); |
| ::std::transform( |
| aChartTypeSeq.getConstArray(), aChartTypeSeq.getConstArray() + aChartTypeSeq.getLength(), |
| ::std::back_inserter( aResult ), |
| lcl_ChartTypeToSeriesCnt() ); |
| } |
| } |
| } |
| catch( uno::Exception & ex ) |
| { |
| ASSERT_EXCEPTION( ex ); |
| } |
| |
| return aResult; |
| } |
| |
| ::std::vector< DialogModel::tSeriesWithChartTypeByName > |
| DialogModel::getAllDataSeriesWithLabel() const |
| { |
| ::std::vector< tSeriesWithChartTypeByName > aResult; |
| ::std::vector< Reference< XDataSeriesContainer > > aContainers( |
| getAllDataSeriesContainers()); |
| |
| ::std::copy( aContainers.begin(), aContainers.end(), |
| lcl_DataSeriesContainerAppend( aResult )); |
| return aResult; |
| } |
| |
| DialogModel::tRolesWithRanges DialogModel::getRolesWithRanges( |
| const Reference< XDataSeries > & xSeries, |
| const ::rtl::OUString & aRoleOfSequenceForLabel, |
| const Reference< chart2::XChartType > & xChartType ) const |
| { |
| DialogModel::tRolesWithRanges aResult; |
| try |
| { |
| Reference< data::XDataSource > xSource( xSeries, uno::UNO_QUERY_THROW ); |
| const Sequence< Reference< data::XLabeledDataSequence > > aSeq( xSource->getDataSequences()); |
| ::std::copy( aSeq.getConstArray(), aSeq.getConstArray() + aSeq.getLength(), |
| lcl_RolesWithRangeAppend( aResult, aRoleOfSequenceForLabel )); |
| if( xChartType.is()) |
| { |
| // add missing mandatory roles |
| Sequence< OUString > aRoles( xChartType->getSupportedMandatoryRoles()); |
| OUString aEmptyString; |
| sal_Int32 nI = 0; |
| for( nI=0; nI < aRoles.getLength(); ++nI ) |
| { |
| if( aResult.find( aRoles[nI] ) == aResult.end() ) |
| aResult.insert( DialogModel::tRolesWithRanges::value_type( aRoles[nI], aEmptyString )); |
| } |
| |
| // add missing optional roles |
| aRoles = xChartType->getSupportedOptionalRoles(); |
| for( nI=0; nI < aRoles.getLength(); ++nI ) |
| { |
| if( aResult.find( aRoles[nI] ) == aResult.end() ) |
| aResult.insert( DialogModel::tRolesWithRanges::value_type( aRoles[nI], aEmptyString )); |
| } |
| } |
| } |
| catch( uno::Exception & ex ) |
| { |
| ASSERT_EXCEPTION( ex ); |
| } |
| return aResult; |
| } |
| |
| void DialogModel::moveSeries( |
| const Reference< XDataSeries > & xSeries, |
| eMoveDirection eDirection ) |
| { |
| m_aTimerTriggeredControllerLock.startTimer(); |
| ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) ); |
| |
| Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram()); |
| DiagramHelper::moveSeries( xDiagram, xSeries, eDirection==MOVE_UP ); |
| } |
| |
| Reference< chart2::XDataSeries > DialogModel::insertSeriesAfter( |
| const Reference< XDataSeries > & xSeries, |
| const Reference< XChartType > & xChartType, |
| bool bCreateDataCachedSequences /* = false */ ) |
| { |
| m_aTimerTriggeredControllerLock.startTimer(); |
| ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) ); |
| Reference< XDataSeries > xNewSeries; |
| |
| try |
| { |
| Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() ); |
| ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram ); |
| |
| sal_Int32 nSeriesInChartType = 0; |
| const sal_Int32 nTotalSeries = countSeries(); |
| if( xChartType.is()) |
| { |
| Reference< XDataSeriesContainer > xCnt( xChartType, uno::UNO_QUERY_THROW ); |
| nSeriesInChartType = xCnt->getDataSeries().getLength(); |
| } |
| |
| // create new series |
| xNewSeries.set( |
| lcl_CreateNewSeries( |
| m_xContext, |
| xChartType, |
| nTotalSeries, // new series' index |
| nSeriesInChartType, |
| xDiagram, |
| m_xTemplate, |
| bCreateDataCachedSequences )); |
| |
| // add new series to container |
| if( xNewSeries.is()) |
| { |
| Reference< XDataSeriesContainer > xSeriesCnt( xChartType, uno::UNO_QUERY_THROW ); |
| ::std::vector< Reference< XDataSeries > > aSeries( |
| SequenceToVector( xSeriesCnt->getDataSeries())); |
| ::std::vector< Reference< XDataSeries > >::iterator aIt = |
| ::std::find( aSeries.begin(), aSeries.end(), xSeries ); |
| if( aIt == aSeries.end()) |
| // if we have no series we insert at the first position. |
| aIt = aSeries.begin(); |
| else |
| // vector::insert inserts before, so we have to advance |
| ++aIt; |
| aSeries.insert( aIt, xNewSeries ); |
| xSeriesCnt->setDataSeries( ContainerToSequence( aSeries )); |
| } |
| |
| ThreeDHelper::setScheme( xDiagram, e3DScheme ); |
| } |
| catch( uno::Exception & ex ) |
| { |
| ASSERT_EXCEPTION( ex ); |
| } |
| return xNewSeries; |
| } |
| |
| void DialogModel::deleteSeries( |
| const Reference< XDataSeries > & xSeries, |
| const Reference< XChartType > & xChartType ) |
| { |
| m_aTimerTriggeredControllerLock.startTimer(); |
| ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) ); |
| |
| DataSeriesHelper::deleteSeries( xSeries, xChartType ); |
| } |
| |
| Reference< data::XLabeledDataSequence > DialogModel::getCategories() const |
| { |
| Reference< data::XLabeledDataSequence > xResult; |
| try |
| { |
| if( m_xChartDocument.is()) |
| { |
| Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram()); |
| xResult.set( DiagramHelper::getCategoriesFromDiagram( xDiagram )); |
| } |
| } |
| catch( uno::Exception & ex ) |
| { |
| ASSERT_EXCEPTION( ex ); |
| } |
| return xResult; |
| } |
| |
| void DialogModel::setCategories( const Reference< chart2::data::XLabeledDataSequence > & xCategories ) |
| { |
| if( m_xChartDocument.is()) |
| { |
| Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram()); |
| if( xDiagram.is()) |
| { |
| // categories |
| bool bSupportsCategories = true; |
| |
| Reference< XChartType > xFirstChartType( DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ); |
| if( xFirstChartType.is() ) |
| { |
| sal_Int32 nAxisType = ChartTypeHelper::getAxisType( xFirstChartType, 0 ); // x-axis |
| bSupportsCategories = (nAxisType == AxisType::CATEGORY); |
| } |
| DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram, true, bSupportsCategories ); |
| } |
| } |
| } |
| |
| OUString DialogModel::getCategoriesRange() const |
| { |
| Reference< data::XLabeledDataSequence > xLSeq( getCategories()); |
| OUString aRange; |
| if( xLSeq.is()) |
| { |
| Reference< data::XDataSequence > xSeq( xLSeq->getValues()); |
| if( xSeq.is()) |
| aRange = xSeq->getSourceRangeRepresentation(); |
| } |
| return aRange; |
| } |
| |
| bool DialogModel::isCategoryDiagram() const |
| { |
| bool bRet = false; |
| if( m_xChartDocument.is()) |
| bRet = DiagramHelper::isCategoryDiagram( m_xChartDocument->getFirstDiagram() ); |
| return bRet; |
| } |
| |
| void DialogModel::detectArguments( |
| OUString & rOutRangeString, |
| bool & rOutUseColumns, |
| bool & rOutFirstCellAsLabel, |
| bool & rOutHasCategories ) const |
| { |
| try |
| { |
| uno::Sequence< sal_Int32 > aSequenceMapping;//todo YYYX |
| |
| // Note: unused data is currently not supported in being passed to detectRangeSegmentation |
| if( m_xChartDocument.is()) |
| DataSourceHelper::detectRangeSegmentation( |
| Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY_THROW ), |
| rOutRangeString, aSequenceMapping, rOutUseColumns, rOutFirstCellAsLabel, rOutHasCategories ); |
| } |
| catch( uno::Exception & ex ) |
| { |
| ASSERT_EXCEPTION( ex ); |
| } |
| } |
| |
| bool DialogModel::allArgumentsForRectRangeDetected() const |
| { |
| return DataSourceHelper::allArgumentsForRectRangeDetected( m_xChartDocument ); |
| } |
| |
| void DialogModel::startControllerLockTimer() |
| { |
| m_aTimerTriggeredControllerLock.startTimer(); |
| } |
| |
| bool DialogModel::setData( |
| const Sequence< beans::PropertyValue > & rArguments ) |
| { |
| m_aTimerTriggeredControllerLock.startTimer(); |
| ControllerLockGuard aLockedControllers( Reference< frame::XModel >( m_xChartDocument, uno::UNO_QUERY ) ); |
| |
| Reference< data::XDataProvider > xDataProvider( getDataProvider()); |
| if( ! xDataProvider.is() || |
| ! m_xTemplate.is() ) |
| { |
| OSL_ENSURE( false, "Model objects missing" ); |
| return false; |
| } |
| |
| try |
| { |
| Reference< chart2::data::XDataSource > xDataSource( |
| xDataProvider->createDataSource( rArguments ) ); |
| |
| Reference< chart2::XDataInterpreter > xInterpreter( |
| m_xTemplate->getDataInterpreter()); |
| if( xInterpreter.is()) |
| { |
| Reference< chart2::XDiagram > xDiagram( m_xChartDocument->getFirstDiagram() ); |
| ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram ); |
| |
| ::std::vector< Reference< XDataSeries > > aSeriesToReUse( |
| DiagramHelper::getDataSeriesFromDiagram( xDiagram )); |
| applyInterpretedData( |
| xInterpreter->interpretDataSource( |
| xDataSource, rArguments, |
| ContainerToSequence( aSeriesToReUse )), |
| aSeriesToReUse, |
| true /* bSetStyles */); |
| |
| ThreeDHelper::setScheme( xDiagram, e3DScheme ); |
| } |
| } |
| catch( uno::Exception & ex ) |
| { |
| ASSERT_EXCEPTION( ex ); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| OUString DialogModel::ConvertRoleFromInternalToUI( const OUString & rRoleString ) |
| { |
| return lcl_ConvertRole( rRoleString, true ); |
| } |
| |
| OUString DialogModel::GetRoleDataLabel() |
| { |
| return OUString( String( ::chart::SchResId( STR_OBJECT_DATALABELS ))); |
| } |
| |
| sal_Int32 DialogModel::GetRoleIndexForSorting( const ::rtl::OUString & rInternalRoleString ) |
| { |
| static lcl_tRoleIndexMap aRoleIndexMap; |
| |
| if( aRoleIndexMap.empty()) |
| lcl_createRoleIndexMap( aRoleIndexMap ); |
| |
| lcl_tRoleIndexMap::const_iterator aIt( aRoleIndexMap.find( rInternalRoleString )); |
| if( aIt != aRoleIndexMap.end()) |
| return aIt->second; |
| |
| return 0; |
| } |
| |
| // private methods |
| |
| void DialogModel::applyInterpretedData( |
| const InterpretedData & rNewData, |
| const ::std::vector< Reference< XDataSeries > > & rSeriesToReUse, |
| bool bSetStyles ) |
| { |
| if( ! m_xChartDocument.is()) |
| return; |
| |
| m_aTimerTriggeredControllerLock.startTimer(); |
| Reference< XDiagram > xDiagram( m_xChartDocument->getFirstDiagram()); |
| if( xDiagram.is()) |
| { |
| // styles |
| if( bSetStyles && m_xTemplate.is() ) |
| { |
| sal_Int32 nGroup = 0; |
| sal_Int32 nSeriesCounter = 0; |
| sal_Int32 nNewSeriesIndex = static_cast< sal_Int32 >( rSeriesToReUse.size()); |
| const sal_Int32 nOuterSize=rNewData.Series.getLength(); |
| |
| for(; nGroup < nOuterSize; ++nGroup) |
| { |
| Sequence< Reference< XDataSeries > > aSeries( rNewData.Series[ nGroup ] ); |
| const sal_Int32 nSeriesInGroup = aSeries.getLength(); |
| for( sal_Int32 nSeries=0; nSeries<nSeriesInGroup; ++nSeries, ++nSeriesCounter ) |
| { |
| if( ::std::find( rSeriesToReUse.begin(), rSeriesToReUse.end(), aSeries[nSeries] ) |
| == rSeriesToReUse.end()) |
| { |
| Reference< beans::XPropertySet > xSeriesProp( aSeries[nSeries], uno::UNO_QUERY ); |
| if( xSeriesProp.is()) |
| { |
| // @deprecated: correct default color should be found by view |
| // without setting it as hard attribute |
| Reference< XColorScheme > xColorScheme( xDiagram->getDefaultColorScheme()); |
| if( xColorScheme.is()) |
| xSeriesProp->setPropertyValue( |
| C2U("Color"), uno::makeAny( xColorScheme->getColorByIndex( nSeriesCounter ))); |
| } |
| m_xTemplate->applyStyle( aSeries[nSeries], nGroup, nNewSeriesIndex++, nSeriesInGroup ); |
| } |
| } |
| } |
| } |
| |
| // data series |
| ::std::vector< Reference< XDataSeriesContainer > > aSeriesCnt( getAllDataSeriesContainers()); |
| ::std::vector< Sequence< Reference< XDataSeries > > > aNewSeries( |
| SequenceToVector( rNewData.Series )); |
| |
| OSL_ASSERT( aSeriesCnt.size() == aNewSeries.size()); |
| |
| ::std::vector< Sequence< Reference< XDataSeries > > >::const_iterator aSrcIt( aNewSeries.begin()); |
| ::std::vector< Reference< XDataSeriesContainer > >::iterator aDestIt( aSeriesCnt.begin()); |
| for(; aSrcIt != aNewSeries.end() && aDestIt != aSeriesCnt.end(); |
| ++aSrcIt, ++aDestIt ) |
| { |
| try |
| { |
| OSL_ASSERT( (*aDestIt).is()); |
| (*aDestIt)->setDataSeries( *aSrcIt ); |
| } |
| catch( uno::Exception & ex ) |
| { |
| ASSERT_EXCEPTION( ex ); |
| } |
| } |
| |
| DialogModel::setCategories(rNewData.Categories); |
| } |
| } |
| |
| sal_Int32 DialogModel::countSeries() const |
| { |
| ::std::vector< Reference< XDataSeriesContainer > > aCnt( getAllDataSeriesContainers()); |
| return ::std::accumulate( aCnt.begin(), aCnt.end(), 0, lcl_addSeriesNumber()); |
| } |
| |
| } // namespace chart |