2007-05-22 16:27:50 +00:00
/*************************************************************************
*
2008-04-10 18:43:34 +00:00
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
2007-05-22 16:27:50 +00:00
*
2008-04-10 18:43:34 +00:00
* Copyright 2008 by Sun Microsystems , Inc .
2007-05-22 16:27:50 +00:00
*
2008-04-10 18:43:34 +00:00
* OpenOffice . org - a multi - platform office productivity suite
2007-05-22 16:27:50 +00:00
*
2008-04-10 18:43:34 +00:00
* $ RCSfile : DataBrowserModel . cxx , v $
2008-10-01 07:35:04 +00:00
* $ Revision : 1.6 .16 .2 $
2007-05-22 16:27:50 +00:00
*
2008-04-10 18:43:34 +00:00
* This file is part of OpenOffice . org .
2007-05-22 16:27:50 +00:00
*
2008-04-10 18:43:34 +00:00
* 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 .
2007-05-22 16:27:50 +00:00
*
2008-04-10 18:43:34 +00:00
* 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 ) .
2007-05-22 16:27:50 +00:00
*
2008-04-10 18:43:34 +00:00
* 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 .
2007-05-22 16:27:50 +00:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// MARKER(update_precomp.py): autogen include statement, do not remove
# include "precompiled_chart2.hxx"
# include "DataBrowserModel.hxx"
# include "DialogModel.hxx"
# include "ChartModelHelper.hxx"
# include "DiagramHelper.hxx"
# include "DataSeriesHelper.hxx"
# include "PropertyHelper.hxx"
# include "ControllerLockGuard.hxx"
# include "macros.hxx"
2008-03-06 15:24:36 +00:00
# include "StatisticsHelper.hxx"
2009-03-03 11:39:43 +00:00
# include "ContainerHelper.hxx"
2009-07-02 19:17:43 +00:00
# include "ChartTypeHelper.hxx"
# include "chartview/ExplicitValueProvider.hxx"
2007-05-22 16:27:50 +00:00
# include <com/sun/star/container/XIndexReplace.hpp>
# include <com/sun/star/chart2/XDataSeriesContainer.hpp>
# include <com/sun/star/chart2/XInternalDataProvider.hpp>
# include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
# include <com/sun/star/chart2/XChartTypeContainer.hpp>
# include <com/sun/star/chart2/data/XDataSource.hpp>
# include <com/sun/star/chart2/data/XDataSink.hpp>
# include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
# include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
# include <com/sun/star/chart2/data/XTextualDataSequence.hpp>
# include <rtl/math.hxx>
# include <algorithm>
2008-03-06 15:24:36 +00:00
# if OSL_DEBUG_LEVEL > 1
# include <cstdio>
# endif
2007-05-22 16:27:50 +00:00
using namespace : : com : : sun : : star ;
using : : com : : sun : : star : : uno : : Reference ;
using : : com : : sun : : star : : uno : : Sequence ;
using : : rtl : : OUString ;
namespace
{
OUString lcl_getRole (
const Reference < chart2 : : data : : XDataSequence > & xSeq )
{
OUString aResult ;
Reference < beans : : XPropertySet > xProp ( xSeq , uno : : UNO_QUERY ) ;
if ( xProp . is ( ) )
{
try
{
xProp - > getPropertyValue ( C2U ( " Role " ) ) > > = aResult ;
}
catch ( const uno : : Exception & ex )
{
ASSERT_EXCEPTION ( ex ) ;
}
}
return aResult ;
}
OUString lcl_getRole (
const Reference < chart2 : : data : : XLabeledDataSequence > & xLSeq )
{
OUString aResult ;
if ( xLSeq . is ( ) )
aResult = lcl_getRole ( xLSeq - > getValues ( ) ) ;
return aResult ;
}
OUString lcl_getUIRoleName (
const Reference < chart2 : : data : : XLabeledDataSequence > & xLSeq )
{
OUString aResult ( lcl_getRole ( xLSeq ) ) ;
if ( aResult . getLength ( ) )
2009-06-04 09:41:18 +00:00
aResult = : : chart : : DialogModel : : ConvertRoleFromInternalToUI ( aResult ) ;
2007-05-22 16:27:50 +00:00
return aResult ;
}
void lcl_copyDataSequenceProperties (
const Reference < chart2 : : data : : XDataSequence > & xOldSequence ,
const Reference < chart2 : : data : : XDataSequence > & xNewSequence )
{
Reference < beans : : XPropertySet > xOldSeqProp ( xOldSequence , uno : : UNO_QUERY ) ;
Reference < beans : : XPropertySet > xNewSeqProp ( xNewSequence , uno : : UNO_QUERY ) ;
2008-06-16 11:47:48 +00:00
comphelper : : copyProperties ( xOldSeqProp , xNewSeqProp ) ;
2007-05-22 16:27:50 +00:00
}
bool lcl_SequenceOfSeriesIsShared (
const Reference < chart2 : : XDataSeries > & xSeries ,
const Reference < chart2 : : data : : XDataSequence > & xValues )
{
bool bResult = false ;
if ( ! xValues . is ( ) )
return bResult ;
try
{
OUString aValuesRole ( lcl_getRole ( xValues ) ) ;
OUString aValuesRep ( xValues - > getSourceRangeRepresentation ( ) ) ;
Reference < chart2 : : data : : XDataSource > xSource ( xSeries , uno : : UNO_QUERY_THROW ) ;
Sequence < Reference < chart2 : : data : : XLabeledDataSequence > > aLSeq ( xSource - > getDataSequences ( ) ) ;
for ( sal_Int32 i = 0 ; i < aLSeq . getLength ( ) ; + + i )
if ( aLSeq [ i ] . is ( ) & &
lcl_getRole ( aLSeq [ i ] ) . equals ( aValuesRole ) )
{
// getValues().is(), because lcl_getRole checked that already
bResult = ( aValuesRep = = aLSeq [ i ] - > getValues ( ) - > getSourceRangeRepresentation ( ) ) ;
// assumption: a role appears only once in a series
break ;
}
}
catch ( const uno : : Exception & ex )
{
ASSERT_EXCEPTION ( ex ) ;
}
return bResult ;
}
typedef : : std : : vector < Reference < chart2 : : data : : XLabeledDataSequence > > lcl_tSharedSeqVec ;
lcl_tSharedSeqVec lcl_getSharedSequences ( const Sequence < Reference < chart2 : : XDataSeries > > & rSeries )
{
// @todo: if only some series share a sequence, those have to be duplicated
// and made unshared for all series
lcl_tSharedSeqVec aResult ;
// if we have only one series, we don't want any shared sequences
if ( rSeries . getLength ( ) < = 1 )
return aResult ;
Reference < chart2 : : data : : XDataSource > xSource ( rSeries [ 0 ] , uno : : UNO_QUERY ) ;
Sequence < Reference < chart2 : : data : : XLabeledDataSequence > > aLSeq ( xSource - > getDataSequences ( ) ) ;
for ( sal_Int32 nIdx = 0 ; nIdx < aLSeq . getLength ( ) ; + + nIdx )
{
Reference < chart2 : : data : : XDataSequence > xValues ( aLSeq [ nIdx ] - > getValues ( ) ) ;
bool bShared = true ;
for ( sal_Int32 nSeriesIdx = 1 ; nSeriesIdx < rSeries . getLength ( ) ; + + nSeriesIdx )
{
bShared = lcl_SequenceOfSeriesIsShared ( rSeries [ nSeriesIdx ] , xValues ) ;
if ( ! bShared )
break ;
}
if ( bShared )
aResult . push_back ( aLSeq [ nIdx ] ) ;
}
return aResult ;
}
sal_Int32 lcl_getValuesRepresentationIndex (
const Reference < chart2 : : data : : XLabeledDataSequence > & xLSeq )
{
sal_Int32 nResult = - 1 ;
if ( xLSeq . is ( ) )
{
Reference < chart2 : : data : : XDataSequence > xSeq ( xLSeq - > getValues ( ) ) ;
if ( xSeq . is ( ) )
{
OUString aRep ( xSeq - > getSourceRangeRepresentation ( ) ) ;
nResult = aRep . toInt32 ( ) ;
}
}
return nResult ;
}
struct lcl_RepresentationsOfLSeqMatch : public : : std : : unary_function < Reference < chart2 : : data : : XLabeledDataSequence > , bool >
{
lcl_RepresentationsOfLSeqMatch ( const Reference < chart2 : : data : : XLabeledDataSequence > & xLSeq ) :
m_aValuesRep ( xLSeq . is ( ) ?
( xLSeq - > getValues ( ) . is ( ) ? xLSeq - > getValues ( ) - > getSourceRangeRepresentation ( ) : OUString ( ) )
: OUString ( ) )
{ }
bool operator ( ) ( const Reference < chart2 : : data : : XLabeledDataSequence > & xLSeq )
{
return ( xLSeq . is ( ) & &
xLSeq - > getValues ( ) . is ( ) & &
( xLSeq - > getValues ( ) - > getSourceRangeRepresentation ( ) = = m_aValuesRep ) ) ;
}
private :
OUString m_aValuesRep ;
} ;
struct lcl_RolesOfLSeqMatch : public : : std : : unary_function < Reference < chart2 : : data : : XLabeledDataSequence > , bool >
{
lcl_RolesOfLSeqMatch ( const Reference < chart2 : : data : : XLabeledDataSequence > & xLSeq ) :
m_aRole ( lcl_getRole ( xLSeq ) )
{ }
bool operator ( ) ( const Reference < chart2 : : data : : XLabeledDataSequence > & xLSeq )
{
return lcl_getRole ( xLSeq ) . equals ( m_aRole ) ;
}
private :
OUString m_aRole ;
} ;
bool lcl_ShowCategories ( const Reference < chart2 : : XDiagram > & /* xDiagram */ )
{
// show categories for all charts
return true ;
// return DiagramHelper::isCategoryDiagram( xDiagram );
}
bool lcl_ShowCategoriesAsDataLabel ( const Reference < chart2 : : XDiagram > & xDiagram )
{
return ! : : chart : : DiagramHelper : : isCategoryDiagram ( xDiagram ) ;
}
} // anonymous namespace
namespace chart
{
struct DataBrowserModel : : tDataColumn
{
: : com : : sun : : star : : uno : : Reference <
: : com : : sun : : star : : chart2 : : XDataSeries > m_xDataSeries ;
sal_Int32 m_nIndexInDataSeries ;
: : rtl : : OUString m_aUIRoleName ;
: : com : : sun : : star : : uno : : Reference <
: : com : : sun : : star : : chart2 : : data : : XLabeledDataSequence > m_xLabeledDataSequence ;
eCellType m_eCellType ;
sal_Int32 m_nNumberFormatKey ;
// default CTOR
tDataColumn ( ) : m_nIndexInDataSeries ( - 1 ) , m_eCellType ( TEXT ) , m_nNumberFormatKey ( 0 ) { }
// "full" CTOR
tDataColumn (
const : : com : : sun : : star : : uno : : Reference <
: : com : : sun : : star : : chart2 : : XDataSeries > & xDataSeries ,
sal_Int32 nIndexInDataSeries ,
: : rtl : : OUString aUIRoleName ,
: : com : : sun : : star : : uno : : Reference <
: : com : : sun : : star : : chart2 : : data : : XLabeledDataSequence > xLabeledDataSequence ,
eCellType aCellType ,
sal_Int32 nNumberFormatKey ) :
m_xDataSeries ( xDataSeries ) ,
m_nIndexInDataSeries ( nIndexInDataSeries ) ,
m_aUIRoleName ( aUIRoleName ) ,
m_xLabeledDataSequence ( xLabeledDataSequence ) ,
m_eCellType ( aCellType ) ,
m_nNumberFormatKey ( nNumberFormatKey )
{ }
} ;
struct DataBrowserModel : : implColumnLess : public : : std : : binary_function <
DataBrowserModel : : tDataColumn , DataBrowserModel : : tDataColumn , bool >
{
bool operator ( ) ( const first_argument_type & rLeft , const second_argument_type & rRight )
{
if ( rLeft . m_xLabeledDataSequence . is ( ) & & rRight . m_xLabeledDataSequence . is ( ) )
{
2009-06-04 09:41:18 +00:00
return DialogModel : : GetRoleIndexForSorting ( lcl_getRole ( rLeft . m_xLabeledDataSequence ) ) <
DialogModel : : GetRoleIndexForSorting ( lcl_getRole ( rRight . m_xLabeledDataSequence ) ) ;
2007-05-22 16:27:50 +00:00
}
return true ;
}
} ;
DataBrowserModel : : DataBrowserModel (
const Reference < chart2 : : XChartDocument > & xChartDoc ,
const Reference < uno : : XComponentContext > & xContext ) :
m_xChartDocument ( xChartDoc ) ,
m_xContext ( xContext ) ,
m_apDialogModel ( new DialogModel ( xChartDoc , xContext ) )
{
updateFromModel ( ) ;
}
DataBrowserModel : : ~ DataBrowserModel ( )
{ }
namespace
{
struct lcl_DataSeriesOfHeaderMatches : public : : std : : unary_function < : : chart : : DataBrowserModel : : tDataHeader , bool >
{
lcl_DataSeriesOfHeaderMatches (
const Reference < chart2 : : XDataSeries > & xSeriesToCompareWith ) :
m_xSeries ( xSeriesToCompareWith )
{ }
bool operator ( ) ( const : : chart : : DataBrowserModel : : tDataHeader & rHeader )
{
return ( m_xSeries = = rHeader . m_xDataSeries ) ;
}
private :
Reference < chart2 : : XDataSeries > m_xSeries ;
} ;
}
void DataBrowserModel : : insertDataSeries ( sal_Int32 nAfterColumnIndex )
{
OSL_ASSERT ( m_apDialogModel . get ( ) ) ;
Reference < chart2 : : XInternalDataProvider > xDataProvider (
m_apDialogModel - > getDataProvider ( ) , uno : : UNO_QUERY ) ;
if ( xDataProvider . is ( ) )
{
sal_Int32 nStartCol = 0 ;
Reference < chart2 : : XDiagram > xDiagram ( ChartModelHelper : : findDiagram ( m_xChartDocument ) ) ;
Reference < chart2 : : XChartType > xChartType ;
Reference < chart2 : : XDataSeries > xSeries ;
if ( static_cast < tDataColumnVector : : size_type > ( nAfterColumnIndex ) < = m_aColumns . size ( ) )
xSeries . set ( m_aColumns [ nAfterColumnIndex ] . m_xDataSeries ) ;
2009-07-02 19:17:43 +00:00
sal_Int32 nSeriesNumberFormat = 0 ;
2007-05-22 16:27:50 +00:00
if ( xSeries . is ( ) )
{
xChartType . set ( DiagramHelper : : getChartTypeOfSeries ( xDiagram , xSeries ) ) ;
tDataHeaderVector : : const_iterator aIt (
: : std : : find_if ( m_aHeaders . begin ( ) , m_aHeaders . end ( ) ,
lcl_DataSeriesOfHeaderMatches ( xSeries ) ) ) ;
if ( aIt ! = m_aHeaders . end ( ) )
nStartCol = aIt - > m_nEndColumn ;
2009-07-02 19:17:43 +00:00
Reference < beans : : XPropertySet > xSeriesProps ( xSeries , uno : : UNO_QUERY ) ;
if ( xSeriesProps . is ( ) )
xSeriesProps - > getPropertyValue ( C2U ( " NumberFormat " ) ) > > = nSeriesNumberFormat ;
2007-05-22 16:27:50 +00:00
}
else
{
xChartType . set ( DiagramHelper : : getChartTypeByIndex ( xDiagram , 0 ) ) ;
nStartCol = nAfterColumnIndex ;
}
if ( xChartType . is ( ) )
{
sal_Int32 nOffset = 0 ;
if ( xDiagram . is ( ) & & lcl_ShowCategories ( xDiagram ) )
+ + nOffset ;
// get shared sequences of current series
Reference < chart2 : : XDataSeriesContainer > xSeriesCnt ( xChartType , uno : : UNO_QUERY ) ;
lcl_tSharedSeqVec aSharedSequences ;
if ( xSeriesCnt . is ( ) )
aSharedSequences = lcl_getSharedSequences ( xSeriesCnt - > getDataSeries ( ) ) ;
Reference < chart2 : : XDataSeries > xNewSeries (
m_apDialogModel - > insertSeriesAfter ( xSeries , xChartType , true /* bCreateDataCachedSequences */ ) ) ;
if ( xNewSeries . is ( ) )
{
{
Reference < chart2 : : data : : XDataSource > xSource ( xNewSeries , uno : : UNO_QUERY ) ;
if ( xSource . is ( ) )
{
Sequence < Reference < chart2 : : data : : XLabeledDataSequence > > aLSequences (
xSource - > getDataSequences ( ) ) ;
sal_Int32 nSeqIdx = 0 ;
sal_Int32 nSeqSize = aLSequences . getLength ( ) ;
nStartCol - = ( nOffset - 1 ) ;
for ( sal_Int32 nIndex = nStartCol ;
( nSeqIdx < nSeqSize ) ;
+ + nSeqIdx )
{
lcl_tSharedSeqVec : : const_iterator aSharedIt (
: : std : : find_if ( aSharedSequences . begin ( ) , aSharedSequences . end ( ) ,
lcl_RolesOfLSeqMatch ( aLSequences [ nSeqIdx ] ) ) ) ;
if ( aSharedIt ! = aSharedSequences . end ( ) )
{
aLSequences [ nSeqIdx ] - > setValues ( ( * aSharedIt ) - > getValues ( ) ) ;
aLSequences [ nSeqIdx ] - > setLabel ( ( * aSharedIt ) - > getLabel ( ) ) ;
}
else
{
xDataProvider - > insertSequence ( nIndex - 1 ) ;
// values
Reference < chart2 : : data : : XDataSequence > xNewSeq (
xDataProvider - > createDataSequenceByRangeRepresentation (
OUString : : valueOf ( nIndex ) ) ) ;
lcl_copyDataSequenceProperties (
aLSequences [ nSeqIdx ] - > getValues ( ) , xNewSeq ) ;
aLSequences [ nSeqIdx ] - > setValues ( xNewSeq ) ;
// labels
Reference < chart2 : : data : : XDataSequence > xNewLabelSeq (
xDataProvider - > createDataSequenceByRangeRepresentation (
OUString ( RTL_CONSTASCII_USTRINGPARAM ( " label " ) ) +
OUString : : valueOf ( nIndex ) ) ) ;
lcl_copyDataSequenceProperties (
aLSequences [ nSeqIdx ] - > getLabel ( ) , xNewLabelSeq ) ;
aLSequences [ nSeqIdx ] - > setLabel ( xNewLabelSeq ) ;
+ + nIndex ;
}
}
}
}
2009-07-02 19:17:43 +00:00
if ( nSeriesNumberFormat ! = 0 )
{
//give the new series the same number format as the former series especially for bubble charts thus the bubble size values can be edited with same format immidiately
Reference < beans : : XPropertySet > xNewSeriesProps ( xNewSeries , uno : : UNO_QUERY ) ;
if ( xNewSeriesProps . is ( ) )
xNewSeriesProps - > setPropertyValue ( C2U ( " NumberFormat " ) , uno : : makeAny ( nSeriesNumberFormat ) ) ;
}
2007-05-22 16:27:50 +00:00
updateFromModel ( ) ;
}
}
}
}
void DataBrowserModel : : removeDataSeries ( sal_Int32 nAtColumnIndex )
{
OSL_ASSERT ( m_apDialogModel . get ( ) ) ;
if ( static_cast < tDataColumnVector : : size_type > ( nAtColumnIndex ) < m_aColumns . size ( ) )
{
Reference < chart2 : : XDataSeries > xSeries ( m_aColumns [ nAtColumnIndex ] . m_xDataSeries ) ;
if ( xSeries . is ( ) )
{
m_apDialogModel - > deleteSeries (
xSeries , getHeaderForSeries ( xSeries ) . m_xChartType ) ;
2009-03-03 11:39:43 +00:00
//delete sequences from internal data provider that are not used anymore
//but do not delete sequences that are still in use by the remaining series
Reference < chart2 : : XInternalDataProvider > xDataProvider ( m_apDialogModel - > getDataProvider ( ) , uno : : UNO_QUERY ) ;
Reference < chart2 : : data : : XDataSource > xSourceOfDeletedSeries ( xSeries , uno : : UNO_QUERY ) ;
if ( xDataProvider . is ( ) & & xSourceOfDeletedSeries . is ( ) )
2007-05-22 16:27:50 +00:00
{
: : std : : vector < sal_Int32 > aSequenceIndexesToDelete ;
2009-03-03 11:39:43 +00:00
Sequence < Reference < chart2 : : data : : XLabeledDataSequence > > aSequencesOfDeletedSeries ( xSourceOfDeletedSeries - > getDataSequences ( ) ) ;
Reference < chart2 : : XDataSeriesContainer > xSeriesCnt ( getHeaderForSeries ( xSeries ) . m_xChartType , uno : : UNO_QUERY ) ;
2007-05-22 16:27:50 +00:00
if ( xSeriesCnt . is ( ) )
{
2009-03-03 11:39:43 +00:00
Reference < chart2 : : data : : XDataSource > xRemainingDataSource ( DataSeriesHelper : : getDataSource ( xSeriesCnt - > getDataSeries ( ) ) ) ;
if ( xRemainingDataSource . is ( ) )
2007-05-22 16:27:50 +00:00
{
2009-03-03 11:39:43 +00:00
: : std : : vector < Reference < chart2 : : data : : XLabeledDataSequence > > aRemainingSeq ( ContainerHelper : : SequenceToVector ( xRemainingDataSource - > getDataSequences ( ) ) ) ;
for ( sal_Int32 i = 0 ; i < aSequencesOfDeletedSeries . getLength ( ) ; + + i )
{
: : std : : vector < Reference < chart2 : : data : : XLabeledDataSequence > > : : const_iterator aHitIt (
: : std : : find_if ( aRemainingSeq . begin ( ) , aRemainingSeq . end ( ) ,
lcl_RepresentationsOfLSeqMatch ( aSequencesOfDeletedSeries [ i ] ) ) ) ;
// if not used by the remaining series this sequence can be deleted
if ( aHitIt = = aRemainingSeq . end ( ) )
aSequenceIndexesToDelete . push_back ( lcl_getValuesRepresentationIndex ( aSequencesOfDeletedSeries [ i ] ) ) ;
}
2007-05-22 16:27:50 +00:00
}
}
// delete unnecessary sequences of the internal data
// iterate using greatest index first, so that deletion does not
// shift other sequences that will be deleted later
: : std : : sort ( aSequenceIndexesToDelete . begin ( ) , aSequenceIndexesToDelete . end ( ) ) ;
for ( : : std : : vector < sal_Int32 > : : reverse_iterator aIt (
aSequenceIndexesToDelete . rbegin ( ) ) ; aIt ! = aSequenceIndexesToDelete . rend ( ) ; + + aIt )
{
if ( * aIt ! = - 1 )
xDataProvider - > deleteSequence ( * aIt ) ;
}
}
updateFromModel ( ) ;
}
}
}
void DataBrowserModel : : swapDataSeries ( sal_Int32 nFirstColumnIndex )
{
OSL_ASSERT ( m_apDialogModel . get ( ) ) ;
if ( static_cast < tDataColumnVector : : size_type > ( nFirstColumnIndex ) < m_aColumns . size ( ) - 1 )
{
Reference < chart2 : : XDataSeries > xSeries ( m_aColumns [ nFirstColumnIndex ] . m_xDataSeries ) ;
if ( xSeries . is ( ) )
{
m_apDialogModel - > moveSeries ( xSeries , DialogModel : : MOVE_DOWN ) ;
updateFromModel ( ) ;
}
}
}
void DataBrowserModel : : swapDataPointForAllSeries ( sal_Int32 nFirstIndex )
{
OSL_ASSERT ( m_apDialogModel . get ( ) ) ;
Reference < chart2 : : XInternalDataProvider > xDataProvider (
m_apDialogModel - > getDataProvider ( ) , uno : : UNO_QUERY ) ;
// lockControllers
ControllerLockGuard aGuard ( m_apDialogModel - > getChartModel ( ) ) ;
if ( xDataProvider . is ( ) )
xDataProvider - > swapDataPointWithNextOneForAllSequences ( nFirstIndex ) ;
// unlockControllers
}
void DataBrowserModel : : insertDataPointForAllSeries ( sal_Int32 nAfterIndex )
{
Reference < chart2 : : XInternalDataProvider > xDataProvider (
m_apDialogModel - > getDataProvider ( ) , uno : : UNO_QUERY ) ;
// lockControllers
ControllerLockGuard aGuard ( m_apDialogModel - > getChartModel ( ) ) ;
if ( xDataProvider . is ( ) )
xDataProvider - > insertDataPointForAllSequences ( nAfterIndex ) ;
// unlockControllers
}
void DataBrowserModel : : removeDataPointForAllSeries ( sal_Int32 nAtIndex )
{
Reference < chart2 : : XInternalDataProvider > xDataProvider (
m_apDialogModel - > getDataProvider ( ) , uno : : UNO_QUERY ) ;
// lockControllers
ControllerLockGuard aGuard ( m_apDialogModel - > getChartModel ( ) ) ;
if ( xDataProvider . is ( ) )
xDataProvider - > deleteDataPointForAllSequences ( nAtIndex ) ;
// unlockControllers
}
DataBrowserModel : : tDataHeader DataBrowserModel : : getHeaderForSeries (
const Reference < chart2 : : XDataSeries > & xSeries ) const
{
for ( tDataHeaderVector : : const_iterator aIt ( m_aHeaders . begin ( ) ) ;
aIt ! = m_aHeaders . end ( ) ; + + aIt )
{
if ( aIt - > m_xDataSeries = = xSeries )
return ( * aIt ) ;
}
return tDataHeader ( ) ;
}
Reference < chart2 : : XDataSeries >
DataBrowserModel : : getDataSeriesByColumn ( sal_Int32 nColumn ) const
{
tDataColumnVector : : size_type nIndex ( nColumn ) ;
if ( nIndex < m_aColumns . size ( ) )
return m_aColumns [ nIndex ] . m_xDataSeries ;
return 0 ;
}
DataBrowserModel : : eCellType DataBrowserModel : : getCellType ( sal_Int32 nAtColumn , sal_Int32 /* nAtRow */ )
{
eCellType eResult = TEXT ;
tDataColumnVector : : size_type nIndex ( nAtColumn ) ;
if ( nIndex < m_aColumns . size ( ) )
eResult = m_aColumns [ nIndex ] . m_eCellType ;
return eResult ;
}
double DataBrowserModel : : getCellNumber ( sal_Int32 nAtColumn , sal_Int32 nAtRow )
{
double fResult ;
: : rtl : : math : : setNan ( & fResult ) ;
tDataColumnVector : : size_type nIndex ( nAtColumn ) ;
if ( nIndex < m_aColumns . size ( ) & &
m_aColumns [ nIndex ] . m_xLabeledDataSequence . is ( ) )
{
Reference < chart2 : : data : : XNumericalDataSequence > xData (
m_aColumns [ nIndex ] . m_xLabeledDataSequence - > getValues ( ) , uno : : UNO_QUERY ) ;
if ( xData . is ( ) )
{
Sequence < double > aValues ( xData - > getNumericalData ( ) ) ;
if ( nAtRow < aValues . getLength ( ) )
fResult = aValues [ nAtRow ] ;
}
}
return fResult ;
}
OUString DataBrowserModel : : getCellText ( sal_Int32 nAtColumn , sal_Int32 nAtRow )
{
OUString aResult ;
tDataColumnVector : : size_type nIndex ( nAtColumn ) ;
if ( nIndex < m_aColumns . size ( ) & &
m_aColumns [ nIndex ] . m_xLabeledDataSequence . is ( ) )
{
Reference < chart2 : : data : : XTextualDataSequence > xData (
m_aColumns [ nIndex ] . m_xLabeledDataSequence - > getValues ( ) , uno : : UNO_QUERY ) ;
if ( xData . is ( ) )
{
Sequence < OUString > aValues ( xData - > getTextualData ( ) ) ;
if ( nAtRow < aValues . getLength ( ) )
aResult = aValues [ nAtRow ] ;
}
}
return aResult ;
}
sal_uInt32 DataBrowserModel : : getNumberFormatKey ( sal_Int32 nAtColumn , sal_Int32 /* nAtRow */ )
{
tDataColumnVector : : size_type nIndex ( nAtColumn ) ;
if ( nIndex < m_aColumns . size ( ) )
return m_aColumns [ nIndex ] . m_nNumberFormatKey ;
return 0 ;
}
bool DataBrowserModel : : setCellAny ( sal_Int32 nAtColumn , sal_Int32 nAtRow , const uno : : Any & rValue )
{
bool bResult = false ;
tDataColumnVector : : size_type nIndex ( nAtColumn ) ;
if ( nIndex < m_aColumns . size ( ) & &
m_aColumns [ nIndex ] . m_xLabeledDataSequence . is ( ) )
{
bResult = true ;
try
{
// label
if ( nAtRow = = - 1 )
{
Reference < container : : XIndexReplace > xIndexReplace (
m_aColumns [ nIndex ] . m_xLabeledDataSequence - > getLabel ( ) , uno : : UNO_QUERY_THROW ) ;
xIndexReplace - > replaceByIndex ( 0 , rValue ) ;
}
else
{
Reference < container : : XIndexReplace > xIndexReplace (
m_aColumns [ nIndex ] . m_xLabeledDataSequence - > getValues ( ) , uno : : UNO_QUERY_THROW ) ;
xIndexReplace - > replaceByIndex ( nAtRow , rValue ) ;
}
}
catch ( const uno : : Exception & ex )
{
2007-07-25 07:30:25 +00:00
( void ) ( ex ) ;
2007-05-22 16:27:50 +00:00
bResult = false ;
}
}
return bResult ;
}
bool DataBrowserModel : : setCellNumber ( sal_Int32 nAtColumn , sal_Int32 nAtRow , double fValue )
{
return ( getCellType ( nAtColumn , nAtRow ) = = NUMBER ) & &
setCellAny ( nAtColumn , nAtRow , uno : : makeAny ( fValue ) ) ;
}
bool DataBrowserModel : : setCellText ( sal_Int32 nAtColumn , sal_Int32 nAtRow , const : : rtl : : OUString & rText )
{
return ( getCellType ( nAtColumn , nAtRow ) = = TEXT ) & &
setCellAny ( nAtColumn , nAtRow , uno : : makeAny ( rText ) ) ;
}
sal_Int32 DataBrowserModel : : getColumnCount ( ) const
{
return static_cast < sal_Int32 > ( m_aColumns . size ( ) ) ;
}
sal_Int32 DataBrowserModel : : getMaxRowCount ( ) const
{
sal_Int32 nResult = 0 ;
tDataColumnVector : : const_iterator aIt ( m_aColumns . begin ( ) ) ;
for ( ; aIt ! = m_aColumns . end ( ) ; + + aIt )
{
if ( aIt - > m_xLabeledDataSequence . is ( ) )
{
Reference < chart2 : : data : : XDataSequence > xSeq (
aIt - > m_xLabeledDataSequence - > getValues ( ) ) ;
if ( ! xSeq . is ( ) )
continue ;
sal_Int32 nLength ( xSeq - > getData ( ) . getLength ( ) ) ;
if ( nLength > nResult )
nResult = nLength ;
}
}
return nResult ;
}
OUString DataBrowserModel : : getRoleOfColumn ( sal_Int32 nColumnIndex ) const
{
if ( nColumnIndex ! = - 1 & &
static_cast < sal_uInt32 > ( nColumnIndex ) < m_aColumns . size ( ) )
return m_aColumns [ nColumnIndex ] . m_aUIRoleName ;
return OUString ( ) ;
}
Reference < chart2 : : data : : XLabeledDataSequence >
DataBrowserModel : : getCategories ( ) const throw ( )
{
OSL_ASSERT ( m_apDialogModel . get ( ) ) ;
return m_apDialogModel - > getCategories ( ) ;
}
2008-06-16 11:47:48 +00:00
const DataBrowserModel : : tDataHeaderVector & DataBrowserModel : : getDataHeaders ( ) const
2007-05-22 16:27:50 +00:00
{
return m_aHeaders ;
}
void DataBrowserModel : : updateFromModel ( )
{
if ( ! m_xChartDocument . is ( ) )
return ;
m_aColumns . clear ( ) ;
m_aHeaders . clear ( ) ;
Reference < chart2 : : XDiagram > xDiagram ( ChartModelHelper : : findDiagram ( m_xChartDocument ) ) ;
if ( ! xDiagram . is ( ) )
return ;
// set template at DialogModel
uno : : Reference < lang : : XMultiServiceFactory > xFact ( m_xChartDocument - > getChartTypeManager ( ) , uno : : UNO_QUERY ) ;
DiagramHelper : : tTemplateWithServiceName aTemplateAndService =
DiagramHelper : : getTemplateForDiagram ( xDiagram , xFact ) ;
if ( aTemplateAndService . first . is ( ) )
m_apDialogModel - > setTemplate ( aTemplateAndService . first ) ;
sal_Int32 nHeaderStart = 0 ;
sal_Int32 nHeaderEnd = 0 ;
if ( lcl_ShowCategories ( xDiagram ) )
{
Reference < chart2 : : data : : XLabeledDataSequence > xCategories ( this - > getCategories ( ) ) ;
tDataColumn aCategories ;
aCategories . m_xLabeledDataSequence . set ( xCategories ) ;
if ( lcl_ShowCategoriesAsDataLabel ( xDiagram ) )
2009-06-04 09:41:18 +00:00
aCategories . m_aUIRoleName = DialogModel : : GetRoleDataLabel ( ) ;
2007-05-22 16:27:50 +00:00
else
aCategories . m_aUIRoleName = lcl_getUIRoleName ( xCategories ) ;
aCategories . m_eCellType = TEXT ;
m_aColumns . push_back ( aCategories ) ;
+ + nHeaderStart ;
}
Reference < chart2 : : XCoordinateSystemContainer > xCooSysCnt ( xDiagram , uno : : UNO_QUERY ) ;
if ( ! xCooSysCnt . is ( ) )
return ;
Sequence < Reference < chart2 : : XCoordinateSystem > > aCooSysSeq ( xCooSysCnt - > getCoordinateSystems ( ) ) ;
for ( sal_Int32 nCooSysIdx = 0 ; nCooSysIdx < aCooSysSeq . getLength ( ) ; + + nCooSysIdx )
{
Reference < chart2 : : XChartTypeContainer > xCTCnt ( aCooSysSeq [ nCooSysIdx ] , uno : : UNO_QUERY_THROW ) ;
Sequence < Reference < chart2 : : XChartType > > aChartTypes ( xCTCnt - > getChartTypes ( ) ) ;
2009-07-02 19:17:43 +00:00
sal_Int32 nXAxisNumberFormat = DataSeriesHelper : : getNumberFormatKeyFromAxis ( 0 , aCooSysSeq [ nCooSysIdx ] , 0 , 0 ) ;
2007-05-22 16:27:50 +00:00
for ( sal_Int32 nCTIdx = 0 ; nCTIdx < aChartTypes . getLength ( ) ; + + nCTIdx )
{
Reference < chart2 : : XDataSeriesContainer > xSeriesCnt ( aChartTypes [ nCTIdx ] , uno : : UNO_QUERY ) ;
if ( xSeriesCnt . is ( ) )
{
2009-07-02 19:17:43 +00:00
rtl : : OUString aRoleForDataLabelNumberFormat = ChartTypeHelper : : getRoleOfSequenceForDataLabelNumberFormatDetection ( aChartTypes [ nCTIdx ] ) ;
2007-05-22 16:27:50 +00:00
Sequence < Reference < chart2 : : XDataSeries > > aSeries ( xSeriesCnt - > getDataSeries ( ) ) ;
lcl_tSharedSeqVec aSharedSequences ( lcl_getSharedSequences ( aSeries ) ) ;
for ( lcl_tSharedSeqVec : : const_iterator aIt ( aSharedSequences . begin ( ) ) ;
aIt ! = aSharedSequences . end ( ) ; + + aIt )
{
tDataColumn aSharedSequence ;
aSharedSequence . m_xLabeledDataSequence = * aIt ;
aSharedSequence . m_aUIRoleName = lcl_getUIRoleName ( * aIt ) ;
aSharedSequence . m_eCellType = NUMBER ;
// as the sequences are shared it should be ok to take the first series
// @todo: dimension index 0 for x-values used here. This is just a guess.
// Also, the axis index is 0, as there is usually only one x-axis
2009-07-02 19:17:43 +00:00
aSharedSequence . m_nNumberFormatKey = nXAxisNumberFormat ;
2007-05-22 16:27:50 +00:00
m_aColumns . push_back ( aSharedSequence ) ;
+ + nHeaderStart ;
}
for ( sal_Int32 nSeriesIdx = 0 ; nSeriesIdx < aSeries . getLength ( ) ; + + nSeriesIdx )
{
tDataColumnVector : : size_type nStartColIndex = m_aColumns . size ( ) ;
2009-07-02 19:17:43 +00:00
Reference < chart2 : : XDataSeries > xSeries ( aSeries [ nSeriesIdx ] ) ;
Reference < chart2 : : data : : XDataSource > xSource ( xSeries , uno : : UNO_QUERY ) ;
2007-05-22 16:27:50 +00:00
if ( xSource . is ( ) )
{
Sequence < Reference < chart2 : : data : : XLabeledDataSequence > > aLSeqs ( xSource - > getDataSequences ( ) ) ;
if ( aLSeqs . getLength ( ) = = 0 )
continue ;
nHeaderEnd = nHeaderStart ;
// @todo: dimension index 1 for y-values used here. This is just a guess
2008-10-01 07:35:04 +00:00
sal_Int32 nYAxisNumberFormatKey =
2007-05-22 16:27:50 +00:00
DataSeriesHelper : : getNumberFormatKeyFromAxis (
aSeries [ nSeriesIdx ] , aCooSysSeq [ nCooSysIdx ] , 1 ) ;
2008-03-06 15:24:36 +00:00
sal_Int32 nSeqIdx = 0 ;
for ( ; nSeqIdx < aLSeqs . getLength ( ) ; + + nSeqIdx )
2007-05-22 16:27:50 +00:00
{
2008-10-01 07:35:04 +00:00
sal_Int32 nSequenceNumberFormatKey = nYAxisNumberFormatKey ;
OUString aRole = lcl_getRole ( aLSeqs [ nSeqIdx ] ) ;
2009-07-02 19:17:43 +00:00
if ( aRole . equals ( aRoleForDataLabelNumberFormat ) )
{
nSequenceNumberFormatKey = ExplicitValueProvider : : getExplicitNumberFormatKeyForDataLabel (
Reference < beans : : XPropertySet > ( xSeries , uno : : UNO_QUERY ) , xSeries , - 1 , xDiagram ) ;
}
else if ( aRole . equals ( C2U ( " values-x " ) ) )
nSequenceNumberFormatKey = nXAxisNumberFormat ;
2008-10-01 07:35:04 +00:00
2007-05-22 16:27:50 +00:00
if ( : : std : : find_if ( aSharedSequences . begin ( ) , aSharedSequences . end ( ) ,
lcl_RepresentationsOfLSeqMatch ( aLSeqs [ nSeqIdx ] ) ) = = aSharedSequences . end ( ) )
{
// no shared sequence
m_aColumns . push_back (
tDataColumn (
aSeries [ nSeriesIdx ] ,
nSeqIdx ,
lcl_getUIRoleName ( aLSeqs [ nSeqIdx ] ) ,
aLSeqs [ nSeqIdx ] ,
NUMBER ,
2008-10-01 07:35:04 +00:00
nSequenceNumberFormatKey ) ) ;
2007-05-22 16:27:50 +00:00
+ + nHeaderEnd ;
}
// else skip
}
bool bSwapXAndYAxis = false ;
try
{
Reference < beans : : XPropertySet > xProp ( aCooSysSeq [ nCooSysIdx ] , uno : : UNO_QUERY ) ;
xProp - > getPropertyValue ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( " SwapXAndYAxis " ) ) ) > > = bSwapXAndYAxis ;
}
catch ( const beans : : UnknownPropertyException & ex )
{
2007-07-25 07:30:25 +00:00
( void ) ex ;
2007-05-22 16:27:50 +00:00
}
2008-03-06 15:24:36 +00:00
// add ranges for error bars if present for a series
if ( StatisticsHelper : : usesErrorBarRanges ( aSeries [ nSeriesIdx ] , /* bYError = */ true ) )
2008-10-01 07:35:04 +00:00
addErrorBarRanges ( aSeries [ nSeriesIdx ] , nYAxisNumberFormatKey , nSeqIdx , nHeaderEnd ) ;
2008-03-06 15:24:36 +00:00
2007-05-22 16:27:50 +00:00
m_aHeaders . push_back (
tDataHeader (
aSeries [ nSeriesIdx ] ,
aChartTypes [ nCTIdx ] ,
bSwapXAndYAxis ,
nHeaderStart ,
nHeaderEnd - 1 ) ) ;
2008-03-06 15:24:36 +00:00
2007-05-22 16:27:50 +00:00
nHeaderStart = nHeaderEnd ;
: : std : : sort ( m_aColumns . begin ( ) + nStartColIndex , m_aColumns . end ( ) , implColumnLess ( ) ) ;
}
}
}
}
}
}
2008-03-06 15:24:36 +00:00
void DataBrowserModel : : addErrorBarRanges (
const Reference < chart2 : : XDataSeries > & xDataSeries ,
sal_Int32 nNumberFormatKey ,
sal_Int32 & rInOutSequenceIndex ,
sal_Int32 & rInOutHeaderEnd )
{
try
{
: : std : : vector < Reference < chart2 : : data : : XLabeledDataSequence > > aSequences ;
// x error bars
// ------------
Reference < chart2 : : data : : XDataSource > xErrorSource (
StatisticsHelper : : getErrorBars ( xDataSeries , /* bYError = */ false ) , uno : : UNO_QUERY ) ;
// positive x error bars
Reference < chart2 : : data : : XLabeledDataSequence > xErrorLSequence (
StatisticsHelper : : getErrorLabeledDataSequenceFromDataSource (
xErrorSource ,
/* bPositiveValue = */ true ,
/* bYError = */ false ) ) ;
if ( xErrorLSequence . is ( ) )
aSequences . push_back ( xErrorLSequence ) ;
// negative x error bars
xErrorLSequence . set (
StatisticsHelper : : getErrorLabeledDataSequenceFromDataSource (
xErrorSource ,
/* bPositiveValue = */ false ,
/* bYError = */ false ) ) ;
if ( xErrorLSequence . is ( ) )
aSequences . push_back ( xErrorLSequence ) ;
// y error bars
// ------------
xErrorSource . set (
StatisticsHelper : : getErrorBars ( xDataSeries , /* bYError = */ true ) , uno : : UNO_QUERY ) ;
// positive y error bars
xErrorLSequence . set (
StatisticsHelper : : getErrorLabeledDataSequenceFromDataSource (
xErrorSource ,
/* bPositiveValue = */ true ,
/* bYError = */ true ) ) ;
if ( xErrorLSequence . is ( ) )
aSequences . push_back ( xErrorLSequence ) ;
// negative y error bars
xErrorLSequence . set (
StatisticsHelper : : getErrorLabeledDataSequenceFromDataSource (
xErrorSource ,
/* bPositiveValue = */ false ,
/* bYError = */ true ) ) ;
if ( xErrorLSequence . is ( ) )
aSequences . push_back ( xErrorLSequence ) ;
for ( : : std : : vector < Reference < chart2 : : data : : XLabeledDataSequence > > : : const_iterator aIt ( aSequences . begin ( ) ) ;
aIt ! = aSequences . end ( ) ; + + aIt )
{
m_aColumns . push_back (
tDataColumn (
xDataSeries ,
rInOutSequenceIndex ,
lcl_getUIRoleName ( * aIt ) ,
* aIt ,
NUMBER ,
nNumberFormatKey ) ) ;
+ + rInOutSequenceIndex ;
+ + rInOutHeaderEnd ;
}
}
catch ( const uno : : Exception & ex )
{
ASSERT_EXCEPTION ( ex ) ;
}
}
2007-05-22 16:27:50 +00:00
} // namespace chart