summaryrefslogtreecommitdiff
path: root/chart2/source/controller/dialogs/DialogModel.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'chart2/source/controller/dialogs/DialogModel.cxx')
-rw-r--r--chart2/source/controller/dialogs/DialogModel.cxx849
1 files changed, 849 insertions, 0 deletions
diff --git a/chart2/source/controller/dialogs/DialogModel.cxx b/chart2/source/controller/dialogs/DialogModel.cxx
new file mode 100644
index 000000000000..f32a882aa1e9
--- /dev/null
+++ b/chart2/source/controller/dialogs/DialogModel.cxx
@@ -0,0 +1,849 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 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 ) )
+{
+ createBackup();
+}
+
+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;
+}
+
+// static
+OUString DialogModel::ConvertRoleFromInternalToUI( const OUString & rRoleString )
+{
+ return lcl_ConvertRole( rRoleString, true );
+}
+
+// static
+OUString DialogModel::GetRoleDataLabel()
+{
+ return OUString( String( ::chart::SchResId( STR_OBJECT_DATALABELS )));
+}
+
+// static
+
+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::createBackup()
+{
+ OSL_ENSURE( ! m_xBackupChartDocument.is(), "Cloning already cloned model" );
+ try
+ {
+ Reference< util::XCloneable > xCloneable( m_xChartDocument, uno::UNO_QUERY_THROW );
+ m_xBackupChartDocument.set( xCloneable->createClone(), uno::UNO_QUERY_THROW );
+ }
+ catch( uno::Exception & ex )
+ {
+ ASSERT_EXCEPTION( ex );
+ }
+}
+
+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